C# mapscript를 사용하여 GetFeaturInfo WMS 요청을 처리하려고합니다. mapscript를 사용하기 전에 우리 소프트웨어는 WMS 요청을 IIS에서 호스팅되는 CGI 맵 서버로 전달했습니다. 이렇게하면 각 쿼리 된 레이어와 연결된 html 템플릿이 처리되고 데이터 템플릿의 여러 토큰이 대체됩니다.mapscript를 사용하여 레이어 템플릿을 처리하여 WMS GetFeatureInfo 요청에 응답하는 방법
mapserver cgi 구현을 사용할 수 없으므로 mapscript를 사용하여이 메커니즘을 C# mapscript 메커니즘을 통해 다시 구현하려고합니다.
내가 지금까지 가지고있는 코드의 요약은 여기에 있습니다. 문제는 processQueryTemplate을 호출하면 AccessViolation Exception이 발생한다는 것입니다. 다음
public string GetFeatureInfoFromWMS(NameValueCollection WMSqueryString)
{
//Set the projection library environment variable used by mapscript.dll
Environment.SetEnvironmentVariable("PROJ_LIB", ProjectionLibraryPath);
string output = string.Empty;
try
{
using (mapObj map = new mapObj(MapFile))
{
//Add aditional layer specific params - ie location of plugins etc
ProcessLayers(map, WMSqueryString);
map.web.metadata.set("wms_onlineresource", WMSOnlineResourceURL);
string xVal = WMSqueryString["X"];
string yVal = WMSqueryString["Y"];
if (xVal == null || yVal == null)
{
throw new ArgumentNullException("The X or Y point value has not been suppplied in the GetFeatureInfo request");
}
double pointX = 0.0;
double pointY = 0.0;
try
{
pointX = Convert.ToDouble(xVal);
pointY = Convert.ToDouble(yVal);
}
catch (Exception e)
{
throw new ArgumentException("The X or Y point value supplied in the GetFeatureInfo request is not a valid decimal",e);
}
string layersQS = WMSqueryString["QUERY_LAYERS"];
if (layersQS == null)
{
throw new ArgumentNullException("The QUERY_LAYERS parameter of the WMS GetFeatureInfo request is not specified correctly");
}
//Load the parameters from the wms request into the map
using (OWSRequest request = new OWSRequest())
{
for (int i = 0; i < WMSqueryString.Count; i++)
{
request.setParameter(WMSqueryString.GetKey(i), WMSqueryString.Get(i));
}
string wmsVersion = WMSqueryString["VERSION"];
if (wmsVersion == null || wmsVersion == string.Empty) wmsVersion = DEFAULT_WMS_VERSION;
map.loadOWSParameters(request, wmsVersion);
}
//Reproject X & Y pixel co-ordinates in map co-ordintes.
double minX = map.extent.minx;
double maxX = map.extent.maxx;
double geoX = minX + ((pointX/(double)map.width) * (maxX - minX));
double minY = map.extent.miny;
double maxY = map.extent.maxy;
double geoY = maxY - ((pointY/(double)map.height) * (maxY - minY));
string[] queryLayers = layersQS.Split(',');
using (pointObj point = new pointObj(geoX, geoY, 0, 0))
{
foreach (string layerName in queryLayers)
{
using (layerObj layer = map.getLayerByName(layerName))
{
int queryResult = layer.queryByPoint(map, point, (int)MS_QUERY_MODE.MS_QUERY_SINGLE, -1);
}
}
}
map.prepareQuery();
string[] names = { "Token1" };
string[] values = { "Value1" };
//BANG!!!!!!
output = map.processQueryTemplate(names, values, 10);
}
return output;
}
catch (Exception ex)
{
throw;
}
}
연관된 맵 파일이다 : 맵 파일
MAP
#
# Start of map file
#
NAME esdm
STATUS ON
TEMPLATEPATTERN "."
SIZE 400 600
UNITS meters
EXTENT 0 0 800000 1200000
IMAGECOLOR 255 255 255
FONTSET fonts.txt
#DEBUG ON
IMAGETYPE PNG
PROJECTION
"init=epsg:27700"
END
OUTPUTFORMAT
NAME "png"
DRIVER "GD/PNG"
IMAGEMODE RGBA
MIMETYPE image/png
EXTENSION png
TRANSPARENT ON
END
# OUTPUTFORMAT
# NAME "imagemap"
# MIMETYPE text/html; driver=imagemap
# DRIVER "imagemap"
# END
#
# Start of web interface definition (including WMS enabling metadata)
#
WEB
METADATA
"wms_title" "SQL mapping data"
"wms_srs" "EPSG:27700 EPSG:4326 EPSG:54004 EPSG:54005 EPSG:900913"
"wms_feature_info_mime_type" "text/plain"
"wms_include_items" "all"
END
END
INCLUDE "mapSymbols.inc"
# BARSActions Point Layer
#-----------------------------------------------------------------------------------------
LAYER
NAME "Actions"
MAXSCALEDENOM 100000000
MINSCALEDENOM 0
METADATA
"wms_title" "BARSActions"
"wfs_title" "BARSActions"
"wms_srs" "EPSG:27700"
END
CONNECTIONTYPE PLUGIN
PLUGIN "SQLPlugin"
DATA "geom from MapLoadTest USING UNIQUE ActionId USING SRID=27700"
FILTER "(OrgUnitId = 1 AND %ActionStatusID% AND %ActionTypeID% AND %AreaIDST(geom)%)"
TYPE POINT
STATUS ON
TOLERANCE 50
TEMPLATE "barsTemplate.htm"
CLASS
COLOR 0 0 255
OUTLINECOLOR 0 0 0
SYMBOL 'star'
SIZE 15
#MAXSIZE 6
#MINSIZE 3
END # end of class object
PROJECTION
"init=epsg:27700"
END
DUMP True
END # end of layer object
# BARSActions Polygon Layer
#-----------------------------------------------------------------------------------------
LAYER
NAME "ActionsPolygons"
MAXSCALEDENOM 100000000
MINSCALEDENOM 0
METADATA
"wms_title" "BARSActionsPolygons"
"wfs_title" "BARSActionsPolygons"
"wms_srs" "EPSG:27700"
END
CONNECTIONTYPE PLUGIN
PLUGIN "SQLPlugin"
DATA "geom from MapLoadTest USING UNIQUE ActionId USING SRID=27700"
FILTER "(OrgUnitId = 2 AND ActionID = 200 AND %ActionStatusID% AND %ActionTypeID% AND %AreaIDST(geom)%)"
TYPE POLYGON
STATUS ON
TOLERANCE 50
TEMPLATE "barsTemplate.htm"
CLASS
COLOR 0 0 255
OUTLINECOLOR 0 0 0
END # end of class object
PROJECTION
"init=epsg:27700"
END
DUMP True
END # end of layer object
END # Map File
각종 항목 tokenised된다 (즉, SQL 플러그인 위치 데이터에 적용되는 필터)이 콜에 의해 처리 이전 방법에서 ProcessLayers로. 이 메커니즘은지도를 그릴 때 아무런 문제가없는 것처럼 보입니다. queryByPoint에 대한 호출이 작동합니다. 성공을 리턴하고 sql db에 대해 실행 된 조회는 예상 데이터를 리턴합니다.
여기서부터 진행해야 할 곳과 템플릿에서 출력물을 생성하기 위해 수행해야 할 작업이 무엇인지 확신 할 수 없습니다. populated templetes를 반환하기 위해 processQueryTemplate에 대한 호출을 기다리고있었습니다. 나는 또한 prepareQuery가 무엇을 해야하는지에 대해 잘 모릅니다.
건배