0

I am trying to project a Lat/Long value I get from a table to a x/y value that I can use to plot a graphic.

I have seen one way to do this may be to use something like this:

feature.Geometry = mercator.FromGeographic(new MapPoint(lat, lon));
feature.Symbol = LayoutRoot.Resources["TRUCK"] as ESRI.ArcGIS.Client.Symbols.Symbol;
graphicsLayer.Graphics.Add(feature);

However my graphics aren't showing up overlapping my tiled basemap service. I tried the mercator.FromGeographic and Mercator.ToGeographic with unsuccessful results.

My Lat/Long value: 37.1223133333333,-93.27893
Mercator.FromGeographic converted value: X=-10382795.4374339, Y=4469266.40579955, WKID=102100
Mercator.ToGeographic converted value: X=-0.000837860806483038, Y=0.000334317600035687, WKID=4326

Neither of these coordinates put my graphics in the correct location. It should be closer to something like this: X=1424565.77, Y=501970.98. I am trying to learn more about coordinate systems, conversions between systems, etc. Any thoughts on what I can try next?

I am still in the beginner phase of learning programming so thanks for your help. Would you have this as a standalone class in your project?

Here is the code I have so far:

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;
using ESRI.ArcGIS.Client.Symbols;
using System.Runtime.Serialization;
using ESRI.ArcGIS.Client.Tasks;
using System.Windows.Threading;
using ESRI.ArcGIS.Client.Bing;

namespace TruckGPS_Test
{
    public partial class MainPage : UserControl
    {
        //private static ESRI.ArcGIS.Client.Projection.WebMercator mercator = new ESRI.ArcGIS.Client.Projection.WebMercator();

        public MainPage()
        {
            InitializeComponent();
            //AddMarkerGraphics();

            QueryTask queryTaskTruckGPS = new QueryTask("http://gisaprd/ArcGIS/rest/services/TruckGPS/MapServer/8");
            queryTaskTruckGPS.ExecuteCompleted += QueryTask_ExecuteCompletedTruckGPS;
            ESRI.ArcGIS.Client.Tasks.Query queryTruckGPS = new ESRI.ArcGIS.Client.Tasks.Query();
            queryTruckGPS.OutFields.Add("*");
            queryTruckGPS.ReturnGeometry = false;
            queryTruckGPS.Where = "1=1";
            queryTaskTruckGPS.ExecuteAsync(queryTruckGPS, "initial");

            //This timer updates the outage feature count after a 30 second wait
            System.Windows.Threading.DispatcherTimer myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 10, 0);
            myDispatcherTimer.Tick += new EventHandler(Each_Tick);
            myDispatcherTimer.Start();
        }

        public void Each_Tick(object o, EventArgs sender)
        {
            QueryTask queryTaskTruckGPS = new QueryTask("http://gisaprd/ArcGIS/rest/services/TruckGPS/MapServer/8");
            queryTaskTruckGPS.ExecuteCompleted += QueryTask_ExecuteCompletedTruckGPS;
            ESRI.ArcGIS.Client.Tasks.Query queryTruckGPS = new ESRI.ArcGIS.Client.Tasks.Query();
            queryTruckGPS.OutFields.Add("*");
            queryTruckGPS.ReturnGeometry = false;
            queryTruckGPS.Where = "1=1";
            queryTaskTruckGPS.ExecuteAsync(queryTruckGPS, "initial");
        }

        private void QueryTask_ExecuteCompletedTruckGPS(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
        {
            //If Counter isn't working check the web service, make sure the table is added to the map service

            FeatureSet featureSet = args.FeatureSet;
            GraphicsLayer graphicsLayer = MyMap.Layers["TruckGPS"] as GraphicsLayer;
            graphicsLayer.ClearGraphics();
            if (featureSet != null && featureSet.Features.Count > 0)
            {
                ////Check the system time and subtract the time amount wanted from the last gps systime read for movement or idle truck
                //System.DateTime dTime = DateTime.Now;
                //// tSpan is 0 days, 0 hours, 0 minutes, and 0 seconds.
                //System.TimeSpan tSpan = new System.TimeSpan(0, 1, 0, 0);
                //System.DateTime result = dTime - tSpan;
                foreach (ESRI.ArcGIS.Client.Graphic feature in featureSet.Features)
                {
                    if ((feature.Attributes["LONGITUDE"] != null) && (feature.Attributes["LATITUDE"] != null))
                    //&& (feature.Attributes["S"])
                    {
                        var Machine_Name = feature.Attributes["MACHINE_NAME"].ToString();
                        var User_Name = feature.Attributes["USER_NAME"].ToString();
                        double lat = Convert.ToDouble(feature.Attributes["LONGITUDE"]);
                        double lon = Convert.ToDouble(feature.Attributes["LATITUDE"]);

                        feature.Geometry = new MapPoint(lat, lon);
                        //if (User_Name == "CU656")
                        //{
                        //feature.Geometry = mercator.ToGeographic(new MapPoint(lat, lon));
                        feature.Symbol = LayoutRoot.Resources["TRUCK"] as ESRI.ArcGIS.Client.Symbols.Symbol;
                        graphicsLayer.Graphics.Add(feature);
                        //}
                        //else
                        //{
                        //    feature.Symbol = LayoutRoot.Resources["RedMarkerSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol;
                        //    graphicsLayer.Graphics.Add(feature);
                        //}
                    }
                }
                { (MyMap.Layers["TruckGPS"] as GraphicsLayer).Refresh(); };
            }
            else
            {
                graphicsLayer.ClearGraphics();
                //MessageBox.Show("No features returned from query");
            }
        }
        private void MyMap_MouseMove(object sender, System.Windows.Input.MouseEventArgs args)
        {
            if (MyMap.Extent != null)
            {
                System.Windows.Point screenPoint = args.GetPosition(MyMap);
                ScreenCoordsTextBlock.Text = string.Format("Screen Coords: X = {0}, Y = {1}",
                    screenPoint.X, screenPoint.Y);

                ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint = MyMap.ScreenToMap(screenPoint);
                if (MyMap.WrapAroundIsActive)
                    mapPoint = ESRI.ArcGIS.Client.Geometry.Geometry.NormalizeCentralMeridian(mapPoint) as ESRI.ArcGIS.Client.Geometry.MapPoint;
                MapCoordsTextBlock.Text = string.Format("Map Coords: X = {0}, Y = {1}",
                    Math.Round(mapPoint.X, 4), Math.Round(mapPoint.Y, 4));
            }
        } 
    }
}

At what point would I use the geometry service or call the class you stubbed out?

1
  • Note: lat-lon => X-Y is generally termed projection
    – Martin F
    Commented Jun 19, 2014 at 21:34

1 Answer 1

1

You can use the ArcGIS Server REST API out-of-the-box Geometry Service, which has a Project operation, to project a coordinate pair, and then create a graphic from it. The Geometry Service is included in the ESRI Silverlight API as the GeometryService class.

If you haven't your own ArcGIS Server, perhaps you can try the ESRI-published sample servers.

Example class hacked out of one of mine:

using System;
using System.Net;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;
using ESRI.ArcGIS.Client.Tasks;
using System.Collections.Generic;

namespace YabaDabaDoo
{
  /// <summary>
  /// A Service for projecting a point to another coordinate system
  /// and return its coordinates. This service can only operate on
  /// points.
  /// </summary>
  public class ProjectionService
  {
    #region Private/Protected Fields
    private GeometryService _gService = null;
    private SpatialReference _tosr = null;
    #endregion

    public ProjectionService(string gserveUrl, int toSrid)
    {     
      //gserveUrl should be like: http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer
      //if you don't know your SRID, check the lists at: http://resources.arcgis.com/en/help/rest/apiref/usingspatialreferences.html
      _gService = new GeometryService(gserveUrl);
      _tosr = new SpatialReference(toSrid);
      _gService.ProjectCompleted += new EventHandler<GraphicsEventArgs>(_gService_ProjectCompleted);
      _gService.Failed += new EventHandler<TaskFailedEventArgs>(_gService_Failed);
    }

    /// <summary>
    /// This does the real work of the service. In this case, the input SR is that of the graphic.
    /// </summary>
    public void ProjectPoint(Graphic editGraphic)
    {
      try
      {
        //check that the geometry is a point
        if (editGraphic.Geometry is MapPoint)
        {
          _gService.ProjectAsync(new List<Graphic>() { new Graphic() { Geometry = Geometry.Clone(editGraphic.Geometry) } }, _tosr);
        }
        else
        {
          // can't do this
        }
      }
      catch (Exception e)
      {
        //TODO: do something sensible
      }
    }
    #endregion

    #region Private/Protected methods - GeometryService event handlers
    void _gService_ProjectCompleted(object sender, GraphicsEventArgs e)
    {
      MapPoint p = e.Results[0].Geometry as MapPoint;

      //TODO: do something with p
    }

    private void _gService_Failed(object sender, TaskFailedEventArgs e)
    {
      //TODO: do something sensible
    }
    #endregion
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.