ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Windows; namespace DistanceQueryOnWrapDatelineMode { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { } }
using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WpfDesktopEdition; namespace DistanceQueryOnWrapDatelineMode { /// <summary> /// Interaction logic for TestWindow.xaml /// </summary> public partial class TestWindow : Window { public TestWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { //Sets the correct map unit wpfMap1.MapUnit = GeographyUnit.DecimalDegree; //Sets the map extent in real coordinates. wpfMap1.CurrentExtent = new RectangleShape(-326,82,-58,-91); wpfMap1.Background = new SolidColorBrush(Color.FromRgb(148, 196, 243)); WorldMapKitWmsWpfOverlay worldMapKitWmsWpfOverlay = new WorldMapKitWmsWpfOverlay(); //Sets the WrapDatelineMode to WrapDateline for the overlay. worldMapKitWmsWpfOverlay.WrappingMode = WrappingMode.WrapDateline; wpfMap1.Overlays.Add("WMK",worldMapKitWmsWpfOverlay); //InMemoryFeatureLayer to put the feature as the result of the spatial query. InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer(); inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle (GeoColor.FromArgb(150, GeoColor.StandardColors.Yellow), GeoColor.StandardColors.DarkGray, 2); inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; LayerOverlay layerOverlay = new LayerOverlay(); //Sets the WrapDatelineMode to WrapDateline for the overlay with the InMemoryFeatureLayer. layerOverlay.WrappingMode = WrappingMode.WrapDateline; layerOverlay.Layers.Add("SelectLayer", inMemoryFeatureLayer); wpfMap1.Overlays.Add("DynamicOverlay", layerOverlay); wpfMap1.Refresh(); } private void wpfMap1_MapClick(object sender, MapClickWpfMapEventArgs e) { try { //Uses the WrapDatelineProjection to create the target pointshape for GetFeatureNearestTo spatial query function. WrapDatelineProjection wrapDatelineProjection = new WrapDatelineProjection(); //Sets the HalfExtentWidth of the wrapdateline overlay we want to apply the projection on. //Here it is 180 because, the full extent width is 360. wrapDatelineProjection.HalfExtentWidth = wpfMap1.Overlays["WMK"].GetBoundingBox().Width / 2;//180; //Gets the valid world coordinate regardless to where the user click on the map wrapDatelineProjection.Open(); Vertex projVertex = wrapDatelineProjection.ConvertToExternalProjection(e.WorldX, e.WorldY); wrapDatelineProjection.Close(); //Here we just use the feature source of the shapefile because we don't display it, we just use it for doing the spatial query. ShapeFileFeatureSource shapeFileFeatureSource = new ShapeFileFeatureSource(@"../../data/countries02.shp"); shapeFileFeatureSource.Open(); //Uses the projected X and Y values for the Spatial Query. Collection<Feature> features = shapeFileFeatureSource.GetFeaturesNearestTo(new PointShape(projVertex), wpfMap1.MapUnit, 1, ReturningColumnsType.NoColumns); shapeFileFeatureSource.Close(); LayerOverlay dynamicOverlay = (LayerOverlay)wpfMap1.Overlays["DynamicOverlay"]; InMemoryFeatureLayer inMemoryFeatureLayer = (InMemoryFeatureLayer)dynamicOverlay.Layers["SelectLayer"]; //Clears the InMemoryFeatureLayer and add the feature as the result of the spatial query. inMemoryFeatureLayer.Open(); inMemoryFeatureLayer.InternalFeatures.Clear(); inMemoryFeatureLayer.InternalFeatures.Add(features[0]); inMemoryFeatureLayer.Close(); //Refreshes only the overlay with the updated InMemoryFeatureLayer. wpfMap1.Refresh(dynamicOverlay); } catch { } finally { } } private void wpfMap1_MouseMove(object sender, MouseEventArgs e) { //Gets the PointShape in world coordinates from screen coordinates. Point point = e.MouseDevice.GetPosition(null); ScreenPointF screenPointF = new ScreenPointF((float)point.X, (float)point.Y); PointShape pointShape = ExtentHelper.ToWorldCoordinate(wpfMap1.CurrentExtent, screenPointF, (float)wpfMap1.Width, (float)wpfMap1.Height); //Uses the WrapDatelineProjection to get the proper decimal degree value on the virtual maps to the right and left of the central map. WrapDatelineProjection wrapDatelineProjection = new WrapDatelineProjection(); //Sets the HalfExtentWidth of the wrapdateline overlay we want to apply the projection on. //Here it is 180 because, the full extent width is 360. wrapDatelineProjection.HalfExtentWidth = wpfMap1.Overlays["WMK"].GetBoundingBox().Width / 2;//180; wrapDatelineProjection.Open(); Vertex projVertex = wrapDatelineProjection.ConvertToExternalProjection(pointShape.X, pointShape.Y); wrapDatelineProjection.Close(); try { //Shows the real coordinates. textBox1.Text = "real X: " + string.Format("{0:0.00}", System.Math.Round(pointShape.X, 2)) + " real Y: " + string.Format("{0:0.00}", System.Math.Round(pointShape.Y, 2)); //Shows the decimal degrees after the WrapDatelineProjection textBox2.Text = "Decimal Degree X: " + string.Format("{0:0.00}", System.Math.Round(projVertex.X, 2)) + " Decimal Degree Y: " + string.Format("{0:0.00}", System.Math.Round(projVertex.Y, 2)); //Shows the Decimal Minutes Seconds format after the WrapDatelineProjection textBox3.Text = "Long.: " + DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(projVertex.X) + " Lat.: " + DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(projVertex.Y); } catch { } finally { } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using ThinkGeo.MapSuite.Core; namespace DistanceQueryOnWrapDatelineMode { class WrapDatelineProjection : Projection, IDisposable { private double nHalfExtentWidth; private double [] an = new double[100]; private double[] an_minus = new double[100]; //Property for half the extent of the central map. //For example: //If the map is in decimal degree, the value will be 180 (worldMapKitWmsWpfOverlay.GetBoundingBox().Width / 2). //If the map is using Google map, the value will be 14000955.5 (googleMapsOverlay.GetBoundingBox().Width / 2) public double HalfExtentWidth { get { return nHalfExtentWidth; } set { nHalfExtentWidth = value; double sum = 0; for (int i = 0; i <= an.Length - 1; i += 1) { an[i] = nHalfExtentWidth + sum; sum = sum + (nHalfExtentWidth * 2); } sum = 0; for (int i = 0; i <= an_minus.Length - 1; i += 1) { an_minus[i] = -nHalfExtentWidth - sum; sum = sum + (nHalfExtentWidth * 2); } } } protected override Vertex[] ConvertToExternalProjectionCore(double[] x, double[] y) { Vertex[] vertices = new Vertex[x.Length]; for (int i = 0; i < vertices.Length; i++) { if ((x[i] > HalfExtentWidth)|| (x[i] < (-HalfExtentWidth))) { double realx = GetAp(x[i]); vertices[i] = new Vertex(realx, y[i]); } else { vertices[i] = new Vertex(x[i], y[i]); } } return vertices; } private double GetAp(double Xp) { double result = 0; if (Xp > 0) { for (int i = 0; i < an.Length - 2; i++) { if ((Xp >= an[i]) && (Xp < an[i|+ 1])) { result = Xp - (an[i] + HalfExtentWidth); break; } } } else { for (int i = 0; i < an_minus.Length - 2; i++) { if ((Xp <= an_minus[i]) && (Xp > an_minus[i|+ 1])) { result = Xp + (an[i] + HalfExtentWidth); break; } } } return result; } protected override Vertex[] ConvertToInternalProjectionCore(double[] x, double[] y) { throw new NotImplementedException(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { Close(); } } }