2

C# mapscript を使用して GetFeatureInfo WMS リクエストを処理しようとしています。mapscript を使用する前は、当社のソフトウェアは IIS でホストされている CGI mapserver に WMS リクエストを渡していました。これにより、クエリされた各レイヤーに関連付けられた html テンプレートが処理され、テンプレート内の多数のトークンがデータに置き換えられました。

mapserver cgi 実装を使用できないため、C# mapscript メカニズムを介して 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

マップ ファイル内のさまざまな項目がトークン化されます (つまり、SQL プラグインの場所とデータに適用されるフィルター)。これは、前のメソッドの ProcessLayers への呼び出しによって処理されます。このメカニズムは、マップを描画するときに問題を引き起こすようには見えません。queryByPoint の呼び出しは機能します。これは成功を返し、SQL データベースに対して実行されたクエリは期待されるデータを返します。

ここからどこに進むべきか、テンプレートから出力を生成するために他に何をする必要があるのか​​ わかりません。processQueryTemplate への呼び出しが、入力されたテンプレートを返すことを期待していました。また、 prepareQuery が何をするべきなのかよくわかりません。

乾杯

4

1 に答える 1

1

テンプレートを機能させる方法がわかりませんでした。ただし、クエリによって返された形状のデータベース 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;
    }
}
于 2011-02-23T16:23:40.237 に答える