gpt4 book ai didi

c# - 如何使用 mapscript 处理图层模板以响应 WMS GetFeatureInfo 请求

转载 作者:太空宇宙 更新时间:2023-11-03 14:22:12 25 4
gpt4 key购买 nike

我正在尝试使用 c# mapscript 处理 GetFeaturInfo WMS 请求。在使用 mapscript 之前,我们的软件将 WMS 请求传递给托管在 IIS 上的 CGI map 服务器。这处理了一个与每个查询层关联的 html 模板,并用模板中的一些标记替换了数据。

我们不能使用 mapserver cgi 实现,所以我试图通过 C# mapscript 机制使用 mapscript 重新实现这个机制。

我到目前为止的代码摘要在这里。问题是对 processQueryTemplate 的调用导致抛出 AccessViolation 异常。

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 文件如下:

    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

map 文件中的各种项目被标记化(即 sql 插件位置和应用于数据的过滤器)这是通过在前面的方法中调用 ProcessLayers 来处理的。这种机制在绘制 map 时似乎不会造成任何问题。对 queryByPoint 的调用有效。它返回成功,并且针对 sql db 运行的查询返回预期数据。

我不确定从哪里开始以及还需要做什么才能从模板中生成输出。我期待调用 processQueryTemplate 返回填充的模板。我也不太清楚 prepareQuery 应该做什么。

干杯

最佳答案

从来没有弄清楚如何让模板工作。但是我设法获得了查询返回的形状的数据库 ID。然后,我使用这些在别处准备 HTML 结果。

请注意,我使用 map.querybypoint 来处理存在图层组的情况(在这种情况下,图层组名称将作为 wms 请求中的图层名称出现。

/// <summary>
/// Handles a GetFeature info request and returns matching ActionID's.
/// </summary>
/// <param name="WMSqueryString">The WM squery string.</param>
/// <returns>A list of matching action ID's.</returns>
/// <exception cref="ArgumentNullException">Thrown if the X or Y point values are not supplied in the WMS GetFeatureInfo request</exception>
/// <exception cref="ArgumentException">Thrown in the X or Y point values supplied in the WMS GetFeatureInfo request cannot be converted to valid doubles</exception>
public List<int> GetFeatureInfoActionID(NameValueCollection WMSqueryString)
{
//Set the projection library environment variable used by mapscript.dll
Environment.SetEnvironmentVariable("PROJ_LIB", ProjectionLibraryPath);

try
{
List<int> resultsList = new List<int>();

using (mapObj map = new mapObj(MapFile))
{
ProcessLayers(map, WMSqueryString);

map.web.metadata.set("wms_onlineresource", WMSOnlineResourceURL);

//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);
}

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);
}

//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));

MS_RETURN_VALUE queryResult;

using (pointObj point = new pointObj(geoX, geoY, 0, 0))
{
queryResult = (MS_RETURN_VALUE)map.queryByPoint(point, (int)MS_QUERY_MODE.MS_QUERY_MULTIPLE, -1);
}

if (queryResult != MS_RETURN_VALUE.MS_SUCCESS)
{
return null;
}

map.prepareQuery();

for (int layerIndex = 0; layerIndex < map.numlayers; layerIndex++)
{
using (layerObj layer = map.getLayer(layerIndex))
{
int resultCount = layer.getNumResults();
if (resultCount > 0)
{
layer.open();

for (int resultIndex = 0; resultIndex < resultCount; resultIndex++)
{
using (resultCacheMemberObj resultCache = layer.getResult(resultIndex))
{
int actionID = resultCache.shapeindex;
if (actionID != 0 && resultsList.Contains(actionID) == false)
{
resultsList.Add(actionID);
}
}
}

layer.close();
}
}
}

}
return resultsList;
}
catch (Exception ex)
{
throw;
}
}

关于c# - 如何使用 mapscript 处理图层模板以响应 WMS GetFeatureInfo 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5041566/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com