MS RFC 31:从字符串加载MapServer对象

日期

2007年6月19日

作者

史蒂夫·莱姆

联系

明尼苏达州第纳尔的史蒂夫·莱姆

版本

5.0

状态

接受(2007/06/22)实施

描述:这个RFC解决了MapServer标记器(在maplexer.l和mapfile.c中)从字符串和文件工作的能力。一个映射文件范围的功能被添加到5.0源中,这个RFC通过mapscript和url查看加载mapserver对象(层、scalebars等)。

当前状态

目前,mapserver可以使用msloadmapfromstring从文本块加载整个mapfile。这是5.0中的新功能。MapServer长期以来能够使用map_object_属性语法(例如map_scalebar_units)通过url加载/修改单个值。

URL支持的问题在于,它对用户来说很麻烦,并且导致mapfile.c中大量重复的代码,这使得维护变得困难。开发人员通常会添加一个参数,但忘记添加一个URL等价物。这个提议消除了多余的代码,并依赖于每个对象的一个标记化功能。

C API更改

所有主要对象都将获得一个新的…loadFromString函数(例如msloadLayerFromString等)。这些函数非常简单,可以引用对象和字符串片段。他们会:

  1. 建立lexer线程锁

  2. 将lexer state设置为ms_tokenize_string

  3. 调用LoadObject(例如LoadLayer)

实际上,这是一种加载空对象或更新新对象的方法。

loadobject函数需要进行细微更改:

  1. 每个函数都需要删除对重复属性的限制。如果将参数设置两次,则不应像现在这样生成错误。

  2. 如果已分配内存的属性(例如char*)已经有值并且正在更新,那么它们应该是空闲的。

  3. 对象主关键字(例如,层或类)应允许作为该对象加载器中的标记。分析文件时,对象标识符(例如层)将与父对象一起剥离。例如,一个类被loadLayer识别,这样loadClass就不会遇到令牌。传递包括对象标识符在内的整个对象定义是最有意义的,以便于使用。

MapScript

我乐于接受建议,但我认为最简单的做法是向所有主要对象添加updatefromstring方法。它只需要一个字符串片段,并包装上面提到的…loadfromstring方法。他们会让胡女士成功或胡女士失败。可以考虑向(FreeObject,然后是InitObject)添加一个“clear”方法,这样用户就可以清除内容并从字符串中重新加载。我不确定这对参考计数的影响。

URL

我建议删除所有的loadObjectValue(例如loadLayerValue)函数,以支持整个对象加载。所以,不要做如下的事情:

...map_scalebar_units=meters&map_scalebar_intervals=5&map_scalebar_size=300+2...

你会这样做:

...map_scalebar=UNITS+METERS+INTERVALS+5+SIZE+300+2...

主要对象仍将由map_scalebar或map_legend或map_layername引用,但所有其他属性将通过片段加载。

函数msloadmapparameter将成为msupdatemapfromurl,它将设置lexer状态,获取线程锁,然后调用相应的loadobject函数。

一个问题是,传统上,loadobject函数只从文件中工作,因此对可以更改的内容没有限制。显然,从一个URL中,您不能只允许更改任何内容(例如连接、转储等)。因此,我们将创建一个新的lexer状态,ms-tokenize-url,它只识别我们想要的参数。在这种状态下,lexer不会返回dump或connection等令牌,因此loadobject函数不会处理这些情况。这是对lexer的简单添加。任何暴露在URL修改中的参数都将检查相关的加载块,以确保没有内存泄漏或缓冲区溢出的可能性。

此外,还指出,URL配置不应是默认行为,而应显式启用。启用此功能将通过webobj-urlconfig[模式]中的新参数进行,默认值为空。该模式将是一个正则表达式,可以应用于任何映射变量。因此,可以将更改仅限于带有urlconfig“scalebar”的scalebar对象,或者使用urlconfig“.”允许更多更改。默认情况下不允许任何URL配置。

向后兼容性

URL更改将破坏向后兼容性,但我认为这是一个相对较少使用的选项,并且此更改将非常有益。

实施后注意事项

显然,许多人在移植应用程序以使用新的URL配置时遇到了问题。下面是按对象类型列出的受支持关键字的更多示例和列表。经验法则一:当一个特定对象(如图层、类和样式)中有多个对象时,语法必须以变量名(如map.layer[lakes])唯一标识有问题的对象,然后将修改该对象的mapfile片段作为变量值给出。我们无法一次修改5种样式,因为mapfile语法太自由了。经验法则二:挂起mapobj的任何参数或对象都必须在变量名中引用(例如map.imagetype)。

示例1,更改scaleBar对象:

...&map.scalebar=UNITS+MILES+COLOR+121+121+121+SIZE+300+2&...

示例2,更改演示文稿样式:

...&map.layer[lakes].class[0].style[0]=SYMBOL+crosshatch+COLOR+151+51+151+SIZE+15&...

示例3,创建新功能:

...&map_layer[3]=FEATURE+POINTS+500000+1000000+END+TEXT+'A+test+point'+END&...

按对象类型可更改的对象/关键字。

MAPOBJ(示例-…&map.angle=50&map.imagecolor=255+0+0&…)

angle,config,extent,imagecolor,imagetype,layer,legend,projection,querymap,reference,resolution,
scalebar,size,shapepath,transparent,units,web

layerObj(示例-…&map.layer[lakes].data=mytempshapefile&…

class,data (subject to DATAPATTERN validation),feature,footer (subject to TEMPLATEPATTERN
validation),header (subject to TEMPLATEPATTERN validation),labelitem,opacity,projection,status,
template (subject to TEMPLATEPATTERN validation),tolerance,units

classobj(示例-…&map.layer[lakes].class[0].style[1]=color+255+0+0…)

color,label,outlinecolor,overlaycolor,overlayoutlinecolor,overlaysize,overlaysymbolsize,size,
status,style,symbol,text (note that setting of color etc... should really be done through
a styleObj and not the class shortcuts)

labelobj(示例-…&map.scalebar=label+color+255+0+0+size+15+end)

angle,antialias,backgroundcolor,backgroundshadowcolor,backgroundshadowsize,color,font,
outlinecolor,position,shadowcolor,shadowsize,size

StyleObj(示例-…&map.layer[lakes].class[0].style[0]=color+255+0+0+angle+50+size+30…)

angle,backgroundcolor,color,outlinecolor,size,symbol,width

FeatureObj(示例-…&map_layer[3]=功能+点+500000+1000000+end+text+'a+test+point'+end&…)

points,text,wkt

更多的到来…

昆虫入侵检测系统

https://github.com/MapServer/MapServer/issues/2143

投票历史

+史蒂文、史蒂文、汤克、法兰克、阿塞法伊、佩里克尔斯恩等1人

+从JEFM的0