[mapguide-users] Topology.net and mapguide

Jamo adam.jamison at portbris.com.au
Mon Jan 11 23:14:07 EST 2010


I have posted up a bit of code i'm working on to produce some suggested road
safety signage diagrams on the GIS, given a point of work length and type.
Still working on the dialog just figuring out how best to accomplish the
geometry side of things.

Was wondering if anyone has had much luck with the topology.net libraries
and if they could share some knowledge on how best to implement? I found
this  http://code.google.com/p/tf-net/issues/detail?id=2 MgGeometry issue 

I can get the centreline of works using code below .... however I'm coming
unstuck when it gets to corners and curves.... should be able to fix it with
a bit of maths, but if this topology.net works it'd be great. 

Given a MgGeomery collection and a point I would like to return a geometry
from point in all direction along roads unitl length is greater than a given
distance? and return a MgGeometry that I can use to buffer.

Wall of text below :-)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using OSGeo.MapGuide;
using System.Text;
using System.Collections.Specialized;
using System.IO;

public partial class markup_distancebetween_Default : System.Web.UI.Page
{
    static String sessionID;
    static String mapName;
    static double x;
    static double y;

    class ClosestFeature
    {
        public double Distance { get; set; }
        public String RoadName { get; set; }
        public MgCoordinate UserInput { get; set; }
        public MgGeometry Road { get; set; }
    }


    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Charset = "utf-8";
        if (Page.IsPostBack == false)
            GetRequestParameters();

       
MapGuideApi.MgInitializeWebTier(Request.ServerVariables["APPL_PHYSICAL_PATH"]
+ "../webconfig.ini");
        MgUserInformation cred = new MgUserInformation(sessionID);

        //connect to the site and get a feature service and a resource
service instances
        MgSiteConnection site = new MgSiteConnection();
        site.Open(cred);
        MgResourceService resourceSrvc =
site.CreateService(MgServiceType.ResourceService) as MgResourceService;
        MgFeatureService featureSrvc =
site.CreateService(MgServiceType.FeatureService) as MgFeatureService;

        //Create a temporary map runtime object, locate the layer
        MgMap map = new MgMap(site);
        map.Open(mapName);

        MgGeometryFactory GF = new MgGeometryFactory();
        MgPoint userClick = GF.CreatePoint(GF.CreateCoordinateXY(x, y));
        ClosestFeature result = new ClosestFeature();
        result.UserInput = userClick.Coordinate;

        MgFeatureReader feats =
map.GetLayers().GetItem("plnCLRoads").SelectFeatures(new
MgFeatureQueryOptions());
        MgAgfReaderWriter agf = new MgAgfReaderWriter();
        result.Distance = -1;
        while (feats.ReadNext())
        {
            
            MgGeometry myGeom = agf.Read(feats.GetGeometry("Geometry"));
            if (myGeom.Distance(userClick, null) < result.Distance ||
result.Distance == -1)
            {
                result.Road = myGeom;
                result.Distance = myGeom.Distance(userClick, null);
                if (feats.IsNull("Name") == false)
                {
                    result.RoadName = feats.GetString("Name") + " " +
feats.GetString("Type");
                }
            }
        }
        Response.Write("<BR/><BR/>Therefore the closest Road is <BR/>" +
result.RoadName + " and is " + result.Distance + " m away<BR/>");

        {//test insert geometries into a Featuresource so I can check
visually

            MgClassDefinition myClassDef = new MgClassDefinition();
            myClassDef.SetName("test");
            myClassDef.SetDescription("test" + " Feature Source");
            myClassDef.SetDefaultGeometryPropertyName("testGeom");
            MgDataPropertyDefinition prop = new
MgDataPropertyDefinition("KEY");
            prop.SetDataType(MgPropertyType.Int32);
            prop.SetAutoGeneration(true);
            prop.SetReadOnly(true);
            myClassDef.GetIdentityProperties().Add(prop);
            myClassDef.GetProperties().Add(prop);

            //Set geometry property
            MgGeometricPropertyDefinition geomProp = new
MgGeometricPropertyDefinition("testGeom");
            geomProp.SetGeometryTypes(MgFeatureGeometricType.Point |
MgFeatureGeometricType.Curve | MgFeatureGeometricType.Surface);
            myClassDef.GetProperties().Add(geomProp);

            //Create the schema
            MgFeatureSchema schema = new MgFeatureSchema("test" + "Schema",
"test" + "SchemaDesc");
            schema.GetClasses().Add(myClassDef);
            MgCreateSdfParams sdfParams = new MgCreateSdfParams("MGA-56
(GDA94 / MGA zone 56)", map.GetMapSRS(), schema);
            featureSrvc.CreateFeatureSource(new
MgResourceIdentifier("Library://test.FeatureSource"), sdfParams);
            MgFeatureCommandCollection commands = new
MgFeatureCommandCollection();

            //check if linestring has more than 2 vertexs.

            

            Response.Write(testEdge.IsClosed);

            MgCoordinateIterator lineCoords =
((MgLineString)result.Road).GetCoordinates();
            //for (int curveCount = 0; curveCount <
((MgCurveString)result.Road).Count;curveCount++)
            //{
            //   
Response.Write(((MgCurveString)result.Road).GetSegment(curveCount).Dimension
+ "<BR/>");
            //}

            //MgWktReaderWriter wkt = new MgWktReaderWriter();
            //Response.Write(wkt.Write(result.Road).ToString() + "<BR/>");

            int vertCount = 0;
            while (lineCoords.MoveNext())
            {
                vertCount = vertCount + 1;
            }
            // if more than 2 vertexs then check to see which segment is the
closest.
            if (vertCount != 2)
            {
                lineCoords.Reset();
                MgGeometryCollection lineSegments = new
MgGeometryCollection();
                MgCoordinate lastCoord = null;
                while (lineCoords.MoveNext())
                {
                    MgCoordinate thisCoord = lineCoords.GetCurrent();
                    if (lastCoord != null)
                    {
                        MgCoordinateCollection newLineCoords = new
MgCoordinateCollection();
                        newLineCoords.Add(lastCoord);
                        newLineCoords.Add(thisCoord);
                       
lineSegments.Add(GF.CreateLineString(newLineCoords));
                    }
                    lastCoord = thisCoord;
                }
                lineCoords.Reset();
                lineCoords.MoveNext();
                MgCoordinateCollection lastSegment = new
MgCoordinateCollection();
                lastSegment.Add(lastCoord);
                lastSegment.Add(lineCoords.GetCurrent());
                lineSegments.Add(GF.CreateLineString(lastSegment));

                foreach (MgGeometry geom in lineSegments)
                {
                    if (geom.Distance(userClick, null) == result.Distance)
                    {
                        Response.Write("ooooooh found the closest segment");
                        result.Road = geom;
                    }
                }
            }
            double y2, y1, x2, x1, px, py,ux, uy, lx, ly;
            MgLineString LS = result.Road as MgLineString;
            x1 = LS.GetStartCoordinate().X;
            y1 = LS.GetStartCoordinate().Y;
            x2 = LS.GetEndCoordinate().X;
            y2 = LS.GetEndCoordinate().Y;

            double a = Math.Atan(-(y2 - y1) / (x2 - x1));
            a = a + Math.PI;
            //create point for line of intersection
            px = result.UserInput.X + (result.Distance + 0.01) *
Math.Sin(a);
            py = result.UserInput.Y + (result.Distance + 1) * Math.Cos(a);
            MgCoordinateCollection perpCol = new MgCoordinateCollection();
            perpCol.Add(GF.CreateCoordinateXY(px, py));
            perpCol.Add(result.UserInput);
            
            if (GF.CreateLineString(perpCol).Crosses(result.Road) == false)
            {
                a = a + Math.PI;
                px = result.UserInput.X + (result.Distance + 0.01) *
Math.Sin(a);
                py = result.UserInput.Y + (result.Distance + 0.01) *
Math.Cos(a);
                perpCol.Clear();
                perpCol.Add(GF.CreateCoordinateXY(px, py));
                perpCol.Add(result.UserInput);
            }

            //now I have the perp point of intersection just offset two
points either side.
            MgCoordinate intCoord =
GF.CreateLineString(perpCol).Intersection(result.Road).Centroid.Coordinate;
            a = a + (Math.PI / 2);
            ux = intCoord.X + 10 * Math.Sin(a);
            uy = intCoord.Y + 10 * Math.Cos(a);
            lx = intCoord.X - 10 * Math.Sin(a);
            ly = intCoord.Y - 10 * Math.Cos(a);

            MgCoordinateCollection workSiteCol = new
MgCoordinateCollection();
            workSiteCol.Add(GF.CreateCoordinateXY(ux, uy));
            workSiteCol.Add(GF.CreateCoordinateXY(lx, ly));
            
           
commands.Add(addThis("testGeom",GF.CreateLineString(workSiteCol).Buffer(3,null),
myClassDef.Name));
            
            MgPropertyCollection insertResults;
            insertResults = featureSrvc.UpdateFeatures(new
MgResourceIdentifier("Library://test.FeatureSource"), commands, false);

            MgResourceIdentifier dataSourceId = new
MgResourceIdentifier("Library://test.FeatureSource");
            String myLayerName = "test";
            if (DoesLayerExist(myLayerName, map) == false)
            {
                String layerDef = "Library://test.LayerDefinition";
                MgResourceIdentifier layerDefId = new
MgResourceIdentifier(layerDef);
                MgByteReader layerDefContent =
BuildLayerDefinitionContent("Library://test.FeatureSource", myLayerName);
                resourceSrvc.SetResource(layerDefId, layerDefContent, null);
                MgLayer myLayer = new MgLayer(layerDefId, resourceSrvc);
                myLayer.SetName(myLayerName);
                myLayer.SetLegendLabel(myLayerName);
                myLayer.SetDisplayInLegend(true);
                myLayer.SetSelectable(true);

                MgLayerGroup myLayerGroup;
                if (DoesLayerGroupExist("Redline", map) == false)
                {
                    myLayerGroup = new MgLayerGroup("Redline");
                    myLayerGroup.SetLegendLabel("Redline / Markup");
                    myLayerGroup.SetDisplayInLegend(true);
                    myLayerGroup.SetVisible(true);
                    myLayerGroup.SetDisplayInLegend(true);
                    map.GetLayerGroups().Insert(0, myLayerGroup);
                }
                else
                {
                    myLayerGroup = map.GetLayerGroups().GetItem("Redline");
                }

                myLayer.SetGroup(myLayerGroup);
                map.GetLayers().Insert(0, myLayer);
                myLayer.ForceRefresh();
                map.Save(resourceSrvc);
            }
            RegisterStartupScript("1",
"<script>parent.parent.parent.mapFrame.Refresh();</script>");
        }
    }

    bool DoesLayerGroupExist(String LayerGroupName, MgMap Map)
    {
        MgLayerGroupCollection layerGroups = Map.GetLayerGroups();
        return (layerGroups.Contains(LayerGroupName));
    }

    MgByteReader BuildLayerDefinitionContent(String ResourceId, String
FeatureName)
    {
        String layerTempl = LoadTemplate(Request,
"markup/requests/reqLayerDef1.templ");
        String[] vals = {
                    ResourceId,
                    FeatureName + "Schema:" + FeatureName,
                    "testGeom"
                    };
        layerTempl = Substitute(layerTempl, vals);
        byte[] bytes = Encoding.UTF8.GetBytes(layerTempl);
        MgByteSource src = new MgByteSource(bytes, bytes.Length);
        return src.GetReader();
    }
    bool DoesLayerExist(String LayerName, MgMap Map)
    {
        MgLayerCollection layers = Map.GetLayers();
        return (layers.Contains(LayerName));
    }
    String LoadTemplate(HttpRequest request, String filePath)
    {
        StreamReader sr =
File.OpenText(request.ServerVariables["APPL_PHYSICAL_PATH"] + filePath);
        String template = sr.ReadToEnd();
        return template;

    }
    String Substitute(String templ, String[] vals)
    {
        StringBuilder res = new StringBuilder();
        int index = 0, val = 0;
        bool found;
        do
        {
            found = false;
            int i = templ.IndexOf('%', index);
            if (i != -1)
            {
                found = true;
                res.Append(templ.Substring(index, i - index));
                if (i < templ.Length - 1)
                {
                    if (templ[i + 1] == '%')
                        res.Append('%');
                    else if (templ[i + 1] == 's')
                        res.Append(vals[val++]);
                    else
                        res.Append('@');    //add a character illegal in
jscript so we know the template was incorrect
                    index = i + 2;
                }
            }
        } while (found);
        res.Append(templ.Substring(index));
        return res.ToString();
    }

    MgInsertFeatures addThis(String geomCol, MgGeometry geom, String
className)
    {
        MgAgfReaderWriter agfReaderWriter = new MgAgfReaderWriter();
        MgPropertyCollection PropertyCollection = new
MgPropertyCollection();
        MgByteReader geometryByteReader = agfReaderWriter.Write(geom);
        MgGeometryProperty geometryProperty = new
MgGeometryProperty(geomCol, geometryByteReader);
        PropertyCollection.Add(geometryProperty);
        MgInsertFeatures insertFeatures = new MgInsertFeatures(className,
PropertyCollection);
        return insertFeatures;
    }

    MgGeometry shortGeometry(MgCoordinate click, MgGeometry closest, double
joinDist)
    {
        MgGeometryFactory GF = new MgGeometryFactory();
        joinDist = joinDist + 0.5;
        Response.Write(joinDist + "mts ");
        MgCoordinate arcPt1 = GF.CreateCoordinateXY(click.X + joinDist, 
click.Y);
        MgCoordinate arcPt2 = GF.CreateCoordinateXY(click.X - joinDist, 
click.Y);
        MgCoordinate arcPt3 = GF.CreateCoordinateXY(click.X, click.Y +
joinDist);
        MgCoordinate arcPt4 = GF.CreateCoordinateXY(click.X, click.Y -
joinDist);
        MgArcSegment newGeom = GF.CreateArcSegment(arcPt1,arcPt2,arcPt3);
        MgArcSegment newGeom1 = GF.CreateArcSegment(arcPt2, arcPt1, arcPt4);
        MgCurveSegmentCollection myCurve = new MgCurveSegmentCollection();
        myCurve.Add(newGeom);
        myCurve.Add(newGeom1);
        MgCurvePolygon myPoly =
GF.CreateCurvePolygon(GF.CreateCurveRing(myCurve), null);
        //write out spatial operations
        //Response.Write("<BR/>Contains: " + closest.Contains(myPoly));
        //Response.Write("<BR/>Crosses: " + closest.Crosses(myPoly));
        //Response.Write("<BR/>Disjoint: " + closest.Disjoint(myPoly));
        //Response.Write("<BR/>Intersects: " + closest.Intersects(myPoly));
        //Response.Write("<BR/>Overlaps: " + closest.Overlaps(myPoly));
        //Response.Write("<BR/>Touches: " + closest.Touches(myPoly));
        //Response.Write("<BR/>Within: " + closest.Within(myPoly));
        //if(closest.Intersects(myPoly))
        //    Response.Write("<BR/>" + closest.Intersection(myPoly).Length);
        return myPoly;
    }

    void GetRequestParameters()
    {
        if (Request.HttpMethod == "POST")
            GetParameters(Request.Form);
        else
            GetParameters(Request.QueryString);
    }

    void GetParameters(NameValueCollection parameters)
    {
        mapName = GetParameter(parameters, "MAPNAME");
        sessionID = GetParameter(parameters, "SESSION");
        x = GetDouble(parameters, "x0");
        y = GetDouble(parameters, "y0");
    }
    String GetParameter(NameValueCollection parameters, String name)
    {
        String strval = parameters[name];
        if (null == strval)
            return "";
        return strval.Trim();
    }

    double GetDouble(NameValueCollection parameters, String name)
    {
        double strval = Convert.ToDouble(parameters[name]);
        if (null == strval)
            return 0;
        return strval;
    }
}


-- 
View this message in context: http://n2.nabble.com/Topology-net-and-mapguide-tp4289752p4289752.html
Sent from the MapGuide Users mailing list archive at Nabble.com.


More information about the mapguide-users mailing list