using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using OSGeo.MapGuide.Viewer; using OSGeo.MapGuide; using OSGeo.MapGuide.Viewer.Desktop; using System.IO; namespace AdvancedSample { public partial class MainForm : Form, IMapStatusBar { public MainForm() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { new MapViewerController(mgMapViewer1, //The MgMapViewer mgLegend1, //The MgLegend this, //The IMapStatusBar mgPropertyPane1, //The MgPropertyPane mgDefaultToolbar1); //The MgDefaultToolbar MgdServiceFactory factory = new MgdServiceFactory(); MgdResourceService resSvc = (MgdResourceService)factory.CreateService(MgServiceType.ResourceService); MgResourceIdentifier mapDefId = new MgResourceIdentifier("Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition"); //If this map definition doesn't exist, we ask the user to //load the Sheboygan package if (!resSvc.ResourceExists(mapDefId)) { using (OpenFileDialog diag = new OpenFileDialog()) { diag.Filter = "MapGuide Packages (*.mgp)|*.mgp"; if (diag.ShowDialog() == DialogResult.OK) { MgByteSource source = new MgByteSource(diag.FileName); MgByteReader reader = source.GetReader(); resSvc.ApplyResourcePackage(reader); } else { //No map, nothing to do here Application.Exit(); } } } //Create our runtime map MgdMap map = new MgdMap(mapDefId); //Create our viewer provider MgMapViewerProvider provider = new MgDesktopMapViewerProvider(map); //Initialize our viewer with this provider mgMapViewer1.Init(provider); } public void SetCursorPositionMessage(string message) { lblCoordinates.Text = message; } public void SetFeatureSelectedMessage(string message) { lblMessage.Text = message; } public void SetMapScaleMessage(string message) { lblScale.Text = message; } public void SetMapSizeMessage(string message) { lblSize.Text = message; } private void mgMapViewer1_SelectionChanged(object sender, EventArgs e) { MgSelectionBase selection = mgMapViewer1.GetSelection(); MgReadOnlyLayerCollection layers = selection.GetLayers(); if (layers != null) { for (int i = 0; i < layers.GetCount(); i++) { MgLayerBase layer = layers.GetItem(i); if (layer.Name == "Parcels") //The selected layer is parcels { //Check that we only have one selected object int count = selection.GetSelectedFeaturesCount(layer, layer.FeatureClassName); if (count == 1) { MgFeatureReader reader = null; try { reader = selection.GetSelectedFeatures(layer, layer.FeatureClassName, false); if (reader.ReadNext()) { //Address is in the RPROPAD property if (reader.IsNull("RPROPAD")) MessageBox.Show("Selected parcel has no address"); else MessageBox.Show("Address: " + reader.GetString("RPROPAD")); } } finally //Must close all readers, otherwise connections will leak { reader.Close(); } } else { MessageBox.Show("Please select only one parcel"); } break; } } } } private void btnMeasure_Click(object sender, EventArgs e) { mgMapViewer1.DigitizeLine(OnLineDigitized); } private void OnLineDigitized(double x1, double y1, double x2, double y2) { MgMapBase map = mgMapViewer1.GetMap(); //Create a coordiante system from the map's SRS MgCoordinateSystemFactory csFactory = new MgCoordinateSystemFactory(); MgCoordinateSystem mapCs = csFactory.Create(map.GetMapSRS()); //Invoke the appropriate measure method depending on the type //of coordinate system double dist = 0.0; if (mapCs.GetType() == MgCoordinateSystemType.Geographic) dist = mapCs.MeasureGreatCircleDistance(x1, y1, x2, y2); else dist = mapCs.MeasureEuclideanDistance(x1, y1, x2, y2); //Convert this distance to meters dist = mapCs.ConvertCoordinateSystemUnitsToMeters(dist); MessageBox.Show("Distance is: " + dist + " meters"); } private MgdLayer _pointLayer; private void btnDrawPoint_Click(object sender, EventArgs e) { mgMapViewer1.DigitizePoint(OnPointDrawn); } private void OnPointDrawn(double x, double y) { if (_pointLayer == null) //Our point layer doesn't exist CreateRedlineLayer(); //Now insert our point. This code should look familiar //to you, setting up the MgPropertyCollection for insertion MgPropertyCollection props = new MgPropertyCollection(); MgWktReaderWriter wktRw = new MgWktReaderWriter(); MgAgfReaderWriter agfRw = new MgAgfReaderWriter(); MgGeometry geom = wktRw.Read("POINT (" + x + " " + y + ")"); MgByteReader agf = agfRw.Write(geom); MgGeometryProperty geomProp = new MgGeometryProperty("Geometry", agf); props.Add(geomProp); //Here's where we differ from the official MapGuide API //instead of a monolithic UpdateFeatures() that tries to //do everything, we have individual InsertFeatures/DeleteFeatures/UpdateFeatures //methods. So here's the mg-desktop way MgFeatureReader result = _pointLayer.InsertFeatures(props); result.Close(); //Or if you have have access to the MgdLayer instance /* MgResourceIdentifier fsId = new MgResourceIdentifier(_pointLayer.GetFeatureSourceId()); MgServiceFactory factory = new MgServiceFactory(); MgdFeatureService featSvc = (MgdFeatureService)factory.CreateService(MgServiceType.FeatureService); MgFeatureReader fr = featSvc.InsertFeatures(fsId, "Default:Redline", props); fr.Close(); */ //Now refresh to see your newly drawn point mgMapViewer1.RefreshMap(); } private void CreateRedlineLayer() { MgMapBase map = mgMapViewer1.GetMap(); MgdServiceFactory fact = new MgdServiceFactory(); MgdFeatureService featSvc = (MgdFeatureService)fact.CreateService(MgServiceType.FeatureService); MgResourceService resSvc = (MgResourceService)fact.CreateService(MgServiceType.ResourceService); //Note that mg-desktop does not have a concept of sessions like the //official MapGuide API, but it *does* allow session-based resources //as a way of having temporary resources. Such resources will reside //in a special directory for session resources (specified in Platform.ini) // //You can plug whatever string as the session id, but the resource identifier //must satisfy the session id pattern: // // Session://Path/To/Your.ResourceType // //These files are removed with MgPlatform.Terminate(), which is called in this //application as part of the exiting process. string sessionId = Guid.NewGuid().ToString(); MgResourceIdentifier fsId = new MgResourceIdentifier("Session:" + sessionId + "//Redline.FeatureSource"); MgResourceIdentifier ldfId = new MgResourceIdentifier("Session:" + sessionId + "//Redline.LayerDefinition"); //Create our point redline schema. It looks like this: // // Default // Redline // ID (int32, autogenerated) // Geometry (coordinate system same as map string featureClass = "Default:Redline"; string geometry = "Geometry"; MgFeatureSchema schema = new MgFeatureSchema("Default", "Redline schema"); MgClassDefinition cls = new MgClassDefinition(); cls.Name = "Redline"; MgDataPropertyDefinition id = new MgDataPropertyDefinition("ID"); id.DataType = MgPropertyType.Int32; id.SetAutoGeneration(true); MgGeometricPropertyDefinition geom = new MgGeometricPropertyDefinition(geometry); geom.SpatialContextAssociation = "Default"; geom.GeometryTypes = MgFeatureGeometricType.Curve | MgFeatureGeometricType.Point | MgFeatureGeometricType.Solid | MgFeatureGeometricType.Surface; MgPropertyDefinitionCollection clsProps = cls.GetProperties(); clsProps.Add(id); clsProps.Add(geom); MgPropertyDefinitionCollection idProps = cls.GetIdentityProperties(); idProps.Add(id); cls.DefaultGeometryPropertyName = geometry; MgClassDefinitionCollection classes = schema.GetClasses(); classes.Add(cls); //Create the feature source with this schema. We use the map's //coordinate system for the feature source to ensure features //that we create, will line up with the map MgFileFeatureSourceParams create = new MgFileFeatureSourceParams("OSGeo.SDF", "Default", map.GetMapSRS(), schema); featSvc.CreateFeatureSource(fsId, create); //Then create the layer definition. RedlineLayer.xml contains the template string xml = string.Format(File.ReadAllText("RedlineLayer.xml"), fsId.ToString(), featureClass, geometry); var bytes = Encoding.UTF8.GetBytes(xml); MgByteSource source = new MgByteSource(bytes, bytes.Length); resSvc.SetResource(ldfId, source.GetReader(), null); //Now create the runtime layer and add to map _pointLayer = new MgdLayer(ldfId, resSvc); _pointLayer.LegendLabel = "Redlining"; _pointLayer.Name = "Redline"; _pointLayer.Visible = true; _pointLayer.Selectable = true; _pointLayer.DisplayInLegend = true; var layers = map.GetLayers(); layers.Insert(0, _pointLayer); } } }