SharpMap in Virtual Earth

Topics: SharpMap Project
Feb 19, 2009 at 11:49 AM
Dear all is it possible to open SharpMap in virtual earth.
Thanks
Shakti
Coordinator
Feb 19, 2009 at 12:16 PM
I am not sure if VE supports overlays, what you can do is show VE tiles in OpenLayers and add a sharpmap wms layer overlay to that.. hth jd
Feb 19, 2009 at 12:48 PM
Thanks John for reply
It is possible here is the old article http://www.google.co.in/url?q=http://geekswithblogs.net/JuanDoNeblo/archive/2008/04/13/showing-esri-shapefile-layers-on-a-virtual-earth-map.aspx&ei=0lSdSbGjK5yi6gPl7-HOAw&sa=X&oi=spellmeleon_result&resnum=1&ct=result&cd=1&usg=AFQjCNFhKgKsp-Fl8Wan7UFaoLmu4yKDuQ

But it support old version of sharpmap.

Now I want to do it with the latest version, do you have any idea.
Thanks
Shakti
Coordinator
Feb 19, 2009 at 12:55 PM
In that article it is overlaying json vectors over the VE, not overlaying a rasterized 'map'. In effect it uses SharpMap to extract data from a ShapeFile but not actually render it.
As far as updating the code to the latest version it wouldnt be too hard if you are familiar with the concepts, but the 0.9 trunk is much closer to the articles own code.. 
hth jd 
Feb 19, 2009 at 1:24 PM
Edited Feb 19, 2009 at 3:33 PM
Hello John Thanks
Here is my task detail I hope it will help you more to understand my problem.

Here is a web site where they are displaying parcel maps in VE. It’s the city of Richmond Virginia. Follow the link and zoom in close anywhere on the map. You’ll see green outlines. Those are parcel maps.

http://map.richmondgov.com/parcel/

Here is a summary of the project undertaken by Richmond VA to accomplish the above. They used ESRI ArcServer and MapDotNet, but we will be doing the same thing with SharpMap open source technology (and SQL Server when we get the first part working)

http://www.mapforums.com/city-richmond-virtual-earth-mapdotnet-parcel-mapper-7819.html

Thanks
Shakti
Feb 20, 2009 at 3:06 PM

Shakti,

John is correct in that Juan DoNeblo technique only reads the shapefile, renders it into a jason vector and then by use of the VE api it is redrawn on the VE map.  I am developing a transportation application using Juans technique.  Even so,  I have duplicated many of the techiques in the richmondgov mapping application.

I enhanced Juan's webservice to classify and to filter geometries, to perform the operation similar to the right click on the parcel... in my version I use sharpmap to intersect the geometry where the user clicks and send back the jason vectors and to redaw the selected parcel in a different color.  I also provide a parameter link to perform any data edits necessary.  I also created a pretty nice tool set to measure distance, area, perimeter, buffer radius and quick navagation.

I suspect you could use sharpmap and a wms to create a custom tile layer, then serve it to VE (don't know how efficient that would be though).  Right now, my only limitation is annotations ("Labels").

I would be happy to post any of my work here to help out or have improved upon...

Ted

Feb 20, 2009 at 4:55 PM
Hello Tkowal thanks for your reply
I am not getting that "John is correct in that Juan DoNeblo technique only reads the shapefile" will you please explain that.
Thanks
Shakti
Feb 20, 2009 at 5:40 PM
Shakti,

Juan DoNeblo is using sharpmap ability to read the shapefile.  In the web service example, the service reads a shape file and extracts all the vertices of the polygon as a lat/long pair of points.  To each of those pairs  he is assigning a random color.  The web service returns a list of points,colors back to the web page.  SharpMap at this point does not know anything about the VE Maps or layers.  It's sole purpose is to read the shape file, and give the web service a list of points comprising each polygon.  This data is outputed as a JSON data-interchange format.

The javascript on the web page then converts this JSON list to something the VE api can use.  Then using the VE api draws the polygons from the converted list of lat/longs that were read from the shapefile using SharpMap.  So Juan D. use of sharpmap was for the purpose of reading/interpreting the shapefile.

Does this help?
Feb 21, 2009 at 2:00 PM
Thanks for you reply so can we extracts polygon from the sharpmap and display them on virtual earth?
Thanks
Shakti
Feb 23, 2009 at 12:58 AM
Hey Ted,

I'm quite interested in the work you are talking about.  I've been playing with something similar in OpenLayers but have only just begun.  I'd like ot learn how you've done the VE tools and display, so if you are happy to share your code for doing this I'd love to have a look and possibly work on it (or port your stuff into OpenLayers).

Steve
Coordinator
Feb 23, 2009 at 10:12 AM
Edited Feb 23, 2009 at 10:45 AM
Hi Steve, with openlayers you would use the OpenLayers.Format.GeoJSON object to build the OpenLayers.Feature.Vector objects from the supplied json string. The json string can be created with the GeoJson renderer in the 1.1experimental branch (from memory there are a couple of bugs but it would be easy to fix up, and I think you can use it with 0.9 as well by passing in the map object), or there is a working one in SharpMap v2 (http://sharpmapv2.googlecode.com) At present there is nothing in the OpenLayers code that will make the actual requests but you can easily implement this yourself by subclassing OpenLayers.Layer.HTTPRequest, or using a OpenLayers.Layer.Vector layer and creating your own OpenLayers.Protocol,  or doing it with one of the standard Http request mechanisms.. hth jd
Feb 23, 2009 at 1:42 PM
It's good but still my question was that can we extracts polygon from the sharpmap and display them on virtual earth?

Coordinator
Feb 23, 2009 at 1:53 PM
You can extract data using sharpmap and you can display data on VE but you have to write some of the bridging code yourself..
Feb 23, 2009 at 3:04 PM

Shakti,

Here is a snippet using my version of Juan DeNeblo's web service techique in using Sharp Map in displaying a polygon shape file called Bridges.shp.

//This is the function that initates the Map Service call based upon Juan DoNeblo
//published technique.  This is called from Javascript
function LoadShapefile(fileName,classify,filterColumn,filterValue,cmd)
{
///<summary>Initiates the loading process to display a shapefile on the VE map</summary>
///<param name="fileName" type="string">Shape File Name to Load [name.shp]</param>
///<param name="classify" type="string">Field Name upon which to render symbolology</param>
///<param name="filterColumn" type="string">Column Name upon which to apply a filter></param>
///<param name="filterValue" type="string">Value upon which to filter the dataset</param>
///<param name="cmd" type="string">Filter comparison operator</param>

    /* Here we call the GetMapData asmx ScriptService, passing fileName as
     * a parameter. GetESRIData_success is a callback that will be executed
     * upon successful completion of the method call, and will be passed the
     * return data as parameter. onFailed, on the other side, will be executed
     * in case of failed request */
    sName=fileName;
    fval=filterValue;
    MapService.GetMapData(fileName, classify ,filterColumn,filterValue,cmd,GetESRIData_success, onFailed);
   
    // MessageBox is a function that displays a nice informative box on the map
    MessageBox(true, "Please wait while retrieving Shapefile data...");
}
//-----------------------C.Net Webservice Snippet Using SHARPMAP-----------------------------------
// This is a snippet from my modification of Juan D. Webservice
    public List<Shape> LoadShapefileLayer(string filePath, string classify, string filterColumn, string filterValue, string cmd)
    {
        // SharpMap's Shapefile reader / writer
        ShapeFileProvider sf = null;
        try
        {
            sf = new ShapeFileProvider(filePath);
            sf.Open(false);
            //This class will accept Polygons, Lines and Points
            if (sf.ShapeType != ShapeType.Polygon && sf.ShapeType != ShapeType.PolyLine
                && sf.ShapeType != ShapeType.MultiPoint && sf.ShapeType != ShapeType.Point)
                return null;
                // Initializing the list of Shapes to be returned
                List<Shape> layer = new List<Shape>();
                // Retrieving all the geometries in the Shapefile
                BoundingBox ext = sf.GetExtents();
                // Initialize a Feature Data Set
                FeatureDataSet ds = new FeatureDataSet();
                // Grab all of the Geometries and Data for the Shape
                sf.ExecuteIntersectionQuery(ext, ds);
                //The folowing table should have one row for each record in the shapefile
                FeatureDataTable<uint> dt = ds.Tables[0] as FeatureDataTable<uint>;
                // Iterate through all the rows in the shapefile, assign attribute value if
                // necessary and build export list.
                foreach (FeatureDataRow<uint> row in dt.Rows)
                {
                   string gClass = "";
                   // Assign the classify field  if fieldname is sent
                   if(!string.IsNullOrEmpty(classify))
                   {
                      gClass = row[classify].ToString();
                   }
                   if (!string.IsNullOrEmpty(filterColumn))
                   {
                      //todo: Enumerate the cmd
                      switch (cmd)
                      {
                         case "EQUALS":
                            proccessGeo = string.Compare(row[filterColumn].ToString(), filterValue,
                                                 StringComparison.CurrentCultureIgnoreCase) == 0;
                            break;
                         case "CONTAINS":
                            proccessGeo = row[filterColumn].ToString().Contains(filterValue);
                            break;
                      }
                   }
                   else
                   {
                      proccessGeo = true;
                   }

                   if (proccessGeo)
                   {
                      Geometry geometry = row.Geometry;
                      List<PointF> points = new List<PointF>();
                      // For Reading a Polygon Shape File ...
                      if (sf.ShapeType == ShapeType.Polygon)
                      {
                         Polygon polygon = geometry as SharpMap.Geometries.Polygon;
                         /* Verify that the geometry is actually a polygon. If it is not, just skip it.
                          * Multipolygon support is not yet added */
                         if (polygon != null)
                         {
                            foreach (SharpMap.Geometries.Point vertex in polygon.ExteriorRing.Vertices)
                               points.Add(new PointF((float)vertex.X, (float)vertex.Y));

                            layer.Add(new Shape(points, gClass));

                         }
                      }
                      //For Polylines
       //...srest of the feature types (lines and points) follow the upon the above algorithm
       //...
    return layer; //rendered into a json collection of points
 //---------------------End of the use of SharpMap-------------------------------
 
//Returning back to the Javascript -- Successfull Call
function GetESRIData_success(e)
{    
    if (e!= null)
    {
        //alert(sName);
        AddLayer(e,sName,fval);
    }
}
function AddLayer(jsonLayer,sName)
{
    var features = ConvertShapes(jsonLayer);
    for (var i = 0; i < features.length; i++)
    {
        var classify = jsonLayer[i].Classify;
        DrawFeature(features[i],classify,sName,fval);
    }
    var msg = String.format("{0} shapes from {1} drawn on the map<br/>", features.length, sName)
    MessageBox(true, msg, 5000);
    SetCursor('pointer');

function ConvertShapes(layer)
{
    ///<summary> Converts an array of Shapes to an array of arrays of VELatLong points </summary>
    var features = new Array();
    for (var i = 0; i < layer.length; i++)
    {
        var feature = new Object();
        var llpoints = new Array();
        for (var j = 0; j < layer[i].Points.length; j++)
        {       
            llpoints.push(new VELatLong(layer[i].Points[j].Y, layer[i].Points[j].X));
        }
        feature.Points = llpoints;
        features.push(feature);
    }
    return features;
}
function DrawFeature(feature,classify,sName) 
//EXAMPLE POLYGON RENDERING UPON A VE MAP
// I have previously set up various Blank or Empty VE Layers one of which is named "Bridges"  This was
// done during the page load event.
{
    var shapePolygon = null;
    var shapeLine = null;
    var shapePoint= null;
    var layer = null;
    if (sName=="Bridges.shp")
    {
            layer = GetLayerByTitle("Bridges");
            shapePolygon = new VEShape(VEShapeType.Polygon, feature.Points);
            shapePolygon.SetFillColor(new VEColor(0,0,255,.5));     //(polygon.Colour);
            shapePolygon.SetLineColor(new VEColor(220,20,60,1));        //(polygon.Colour);
           
            shapePolygon.SetLineWidth(1);
            shapePolygon.HideIcon();
            shapePolygon.SetTitle("Bridges");
            shapePolygon.SetDescription("Bridges");   
            layer.AddShape(shapePolygon);
            //Polygon Layer is now drawn to the VE Map
      }  
   //.. on to many different shape files that could be rendered     snipped

Feb 23, 2009 at 4:57 PM
srweal,

My toolset works upon a VE Layer I setup in the Page Load called "Drawing".  Tdocument elements referenced are simple html containers to which I can display updated text.

Below is the listing of my Javascript that performs all the added tool functionality.  Since most of my added tools rely upon a user drawing upon the map, they are divided into feature types.  Example Points deal with Lat/Long entries either plotting or displaying based upon a single point user input. Distance tools are based upon user drawing polylines and perimeter/area based upon drawing polygons.

Tools in use
Point:
    Plot a Lat Long
    Return Lat Long based upon user click
Polyline:
    Cumative distance between user clicked points
Polygon:
    Perimeter
    Area



//Globals
/// <reference path="UtilityFunctions.js" />
/// <reference path="VeJavaScriptIntellisenseHelper.js" />
/// <reference path="MDXVEMap.js" />
/// <reference path="CalcArea.js" />
//var slDrawing = new VEShapeLayer(); 
  
   myCurrentShape = null;
   myDistance = 0;
   tempShape = null;
   tempPoints = null;
   tempDistance = 0;
   myCirclePoints = null;
   tempCircle = null;
   iShapeCount = 1; 
       
function Draw(geomType)
{
   myPoints = new Array();  
   tmpDetails = '';
   slDrawing = GetLayerByTitle("Drawing");
   myCurrentShape = null;
   myGeomType = geomType;
   // Add routine to plot Lat Long from user Input
   // bypassing the added draw events
   map.AttachEvent("onclick", DrawPolyMouseClick);
   map.AttachEvent("onmousemove", MouseMove);
   document.getElementById("myMap").childNodes[0].style.cursor = "all-scroll";
   document.getElementById("txtLat").innerHTML = geomType;
   document.getElementById("txtLon").innerHTML = "Tool";
}
function MouseMove(e)
{
    var x = e.mapX;
    var y = e.mapY;
    pixel = new VEPixel(x, y);
    var LL = map.PixelToLatLong(pixel);
    document.getElementById("txtLat").innerHTML = LL.Latitude;
    document.getElementById("txtLon").innerHTML = LL.Longitude;
}

function DrawPolyMouseClick(e)
{
    var x = e.mapX;
    var y = e.mapY;
    pixel = new VEPixel(x, y);
    var LL = map.PixelToLatLong(pixel);   
    if (myPoints.length == 0 && myGeomType != "point")
    {
        map.DetachEvent("onmousemove", MouseMove);
        map.AttachEvent("onmousemove", DrawPolyMouseMove);
        document.getElementById("divDistance").style.visibility = "visible";
    }
   
    if (myGeomType == "circle" && myPoints.length == 2)
    {
        myPoints[1] = LL;
        myDistance = tempDistance;
    }
    else
    {
        myPoints.push(LL);
        myDistance = myDistance + tempDistance;
    }
   
    if (e.rightMouseButton)
    {
       if(myPoints.length <= 1 && myGeomType != "point"){return;}  //accidental right click on the first point
       if(myPoints.length <=2  && myGeomType == "polygon"){return;} // polygon needs at minimum 3 points
        try
        { 
           map.DetachEvent("onmousemove", MouseMove);
           map.DetachEvent("onmousemove", DrawPolyMouseMove);
           map.DetachEvent("onclick", DrawPolyMouseClick);
           document.getElementById("divDistance").style.visibility = "hidden";
           slDrawing.DeleteShape(tempShape);
           slDrawing.DeleteShape(tempCircle);
        }
        catch (err)
        {
        }
       
        myCurrentShape = "shape" + iShapeCount;
        myDistance = Math.round(myDistance * 10) / 10;
        switch (myGeomType)
        {
            case "polygon":
                myCurrentShape = new VEShape(VEShapeType.Polygon, myPoints); 
                //   Add to the Perimeter the final segment from the last clicked point to the begining
                //   Visually this makes sense because the shape shows a closed polygon, having to
                //   click on the start point is redundant
                myDistance = myDistance + getDistance(LL,tempPoints[0]);
                var mArea = Area(myPoints);
                var fArea = mArea* 10.763911;
                var aArea = fArea / 43560;
                tmpDetails= "Perimeter: " + Math.round(myDistance * 10)/10 + " ft <br />" ;           
                tmpDetails +="Area: " + Math.round(fArea * 10)/10 + " ft2 <br />";
                tmpDetails +="Acres: " + Math.round(aArea * 100)/100;
                break;
            case "polyline":
                myCurrentShape = new VEShape(VEShapeType.Polyline, myPoints);
                tmpDetails = "Distance: " + myDistance + " ft";
                break;
            case "circle":
                myCurrentShape = new VEShape(VEShapeType.Polygon, myCirclePoints);
                tmpDetails = "Radius: " + myDistance + " ft";
                break;
            case "point":
                myCurrentShape = new VEShape(VEShapeType.Pushpin, LL);
                tmpDetails= "Lat: " + LL.Latitude + "<br />Lon: " + LL.Longitude;
                break;
        }
        slDrawing.AddShape(myCurrentShape);
        document.getElementById("txtShapeID").value = "shape" + iShapeCount;
        iShapeCount = iShapeCount + 1;
        var dummy = document.getElementById("divShapeInfo");
        dummy.style.left = e.clientX + "px";
        dummy.style.top = e.clientY + "px";
        dummy.style.visibility = "visible";
        setFocus("txtShapeTitle");
        document.getElementById("myMap").childNodes[0].style.cursor = "";
        document.getElementById("txtLat").innerHTML = '';
        document.getElementById("txtLon").innerHTML = '';

    }
    else
    {
       if (myGeomType == "point")
       {
          map.DetachEvent("onclick", DrawPolyMouseClick);
          map.DetachEvent("onmousemove", DrawPolyMouseMove);
          map.DetachEvent("onmousemove",MouseMove);
          document.getElementById("txtLat").innerHTML = ' ';
          document.getElementById("txtLon").innerHTML = ' ';
          document.getElementById("myMap").childNodes[0].style.cursor = "";
       }
       else
       {
        document.getElementById("myMap").childNodes[0].style.cursor = "all-scroll";
       }
    }
}
function DrawPolyMouseMove(e)
{
    var x = e.mapX;
    var y = e.mapY;
    pixel = new VEPixel(x, y);
    var LL = map.PixelToLatLong(pixel);
    document.getElementById("txtLat").innerHTML = LL.Latitude;
    document.getElementById("txtLon").innerHTML = LL.Longitude;   
    tempPoints = myPoints.slice(0, myPoints.length);
   
    if (myGeomType == "circle" && tempPoints.length == 2)
    {
        tempPoints[1] = LL;
        tempDistance = getDistance(tempPoints[0], LL);
    }
    else
    {
        tempPoints.push(LL);
        tempDistance = getDistance(tempPoints[myPoints.length-1], LL);
    }   
    var dummy = document.getElementById("divDistance");
    dummy.style.left = e.clientX + 1 + "px";
    dummy.style.top = e.clientY + "px";
    //TODO: Polygon displayed is closed so may want to consider showing the perimeter of the
    //      shaped currently displayed instead of the aggregated current distance.
    //      need further input from various users to see what would make more sense.
    dummy.innerHTML = Math.round((myDistance + tempDistance) * 10) / 10;   
    try
    {
        slDrawing.DeleteShape(tempShape);
        slDrawing.DeleteShape(tempCircle);
       

    }
    catch (err)
    {
    }
   
    if (tempPoints.length == 2)
    {
        tempShape = new VEShape(VEShapeType.Polyline, tempPoints);
        tempShape.HideIcon();
        slDrawing.AddShape(tempShape);
        if (myGeomType == "circle")
        {
           GetCircle();
           tempCircle = new VEShape(VEShapeType.Polygon, myCirclePoints);
           tempCircle.HideIcon();
           slDrawing.AddShape(tempCircle);
        }
    }
   
    if (tempPoints.length > 2)
    {
        switch (myGeomType)
        {
            case "polygon":
                tempShape = new VEShape(VEShapeType.Polygon, tempPoints);
                break;
            case "polyline":
                tempShape = new VEShape(VEShapeType.Polyline, tempPoints);
                break;
        }
        tempShape.HideIcon();
        slDrawing.AddShape(tempShape);
    }
}
//calculate distance
function getDistance(p1, p2)
{
   p1Lat = latLonToRadians(p1.Latitude);
 p1Lon = latLonToRadians(p1.Longitude);
 
 p2Lat = latLonToRadians(p2.Latitude);
 p2Lon = latLonToRadians(p2.Longitude); 
 
 var  R= 20925646.36 // earth's mean radius in ft
 //var R = 6371; // earth's mean radius in km
 var dLat  = p2Lat - p1Lat;
 var dLong = p2Lon - p1Lon;
 var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(p1Lat) * Math.cos(p2Lat) * Math.sin(dLong/2) * Math.sin(dLong/2);
 var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
 //var disKm = R * c;
 var disFT = R * c;
 //var disMiles = disKm * 0.6214; 
 return (disFT);
}
//convert lat/long in degrees to radians
function latLonToRadians(point)
///<summary>Convert Latitude and Longitude to Radians</summary>
///<param name="point" type="double">Latitude or Longitude in Decimal Degrees</param>
{
 return point * Math.PI / 180; 
}
//Draw Circle
function GetCircle()
{
    //var R=18946819.16  //Earth radius estimated at florida
    var  R= 20925646.36 // earth's mean radius in ft
    //var R=6378137; // earth's  mean radius in m
    //var R = 6371; // earth's mean radius in km
    var lat = (myPoints[0].Latitude * Math.PI) / 180; //rad
    var lon = (myPoints[0].Longitude * Math.PI) / 180; //rad
    var d = parseFloat(tempDistance) / R;  // d = angular distance covered on earth's surface
    myCirclePoints = new Array();
    for (x = 0; x <= 360; x++)
    {
        var p2 = new VELatLong(0,0)           
        brng = x * Math.PI / 180; //rad
        p2.Latitude = Math.asin(Math.sin(lat)*Math.cos(d) + Math.cos(lat)*Math.sin(d)*Math.cos(brng));
        p2.Longitude = ((lon + Math.atan2(Math.sin(brng)*Math.sin(d)*Math.cos(lat), Math.cos(d)-Math.sin(lat)*Math.sin(p2.Latitude))) * 180) / Math.PI;
        p2.Latitude = (p2.Latitude * 180) / Math.PI;
        myCirclePoints.push(p2);
    }
    return myCirclePoints;
}
function SetInfo()
{
    document.getElementById("txtShapeDetails").value = document.getElementById("txtShapeDetails").value + "<br />" + tmpDetails;
    myCurrentShape.SetTitle(document.getElementById("txtShapeTitle").value);
    myCurrentShape.SetDescription(document.getElementById("txtShapeDetails").value + "<br><a href='javascript:Delete(\"" + myCurrentShape.GetID() + "\")'>Delete</a>");   
    myPoints = new Array();
    tempPoints = null;
    myDistance = 0;
    tempDistance = 0;
   
    var dummy = document.getElementById("divShapeInfo").style.visibility = "hidden";
    document.getElementById("txtShapeTitle").value = "";
    document.getElementById("txtShapeDetails").value = "";
}
function Delete(shape)
{
    var delShape = slDrawing.GetShapeByID(shape);
    slDrawing.DeleteShape(delShape);
   
}
function PlotLatLong()
{
    document.getElementById('getLatLong').style.visibility = "visible";
    setFocus('txtgetLat');
}
function DrawLatLong(myLat,myLong)
{
   //Check for valid Lat Longs
   if (myLat > 26 || myLat < 24)
   {
      MessageBox(true,"Incorrect Latitude Please Re-Enter the number...",2500,false);
      setFocus('txtgetLat');
      return;
   }
      if (myLong > -79 || myLong < -81)
   {
      MessageBox(true,"Incorrect Longitude Please Re-Enter the number...",2500,false);
      setFocus('txtgetLong');
      return;
   }
       LL = new VELatLong(myLat,myLong);
       slDrawing = GetLayerByTitle("Drawing");
       tmpDetails='';
       myCurrentShape = null;
       myCurrentShape = new VEShape(VEShapeType.Pushpin, LL);
       document.getElementById("txtShapeTitle").value = document.getElementById("gllTitle").value;
       document.getElementById("txtShapeDetails").value = document.getElementById("gllDetails").value;
       slDrawing.AddShape(myCurrentShape);
       SetInfo();
       map.PanToLatLong(LL);
       document.getElementById("gllTitle").value = "";
       document.getElementById("gllDetails").value = "";
       document.getElementById("txtgetLat").value = "";
       document.getElementById("txtgetLong").value = "";
       document.getElementById('getLatLong').style.visibility = "hidden";
}

Feb 23, 2009 at 6:37 PM
Hello tkowal
can you please tell me that what is proccessGeo in your code, where I have to declare it?
and also what is PointF?

 case "EQUALS":
                            proccessGeo = string.Compare(row[filterColumn].ToString(), filterValue,
                                                 StringComparison.CurrentCultureIgnoreCase) == 0;

and                     List<PointF> points = new List<PointF>();


Thanks
Shakti



Feb 23, 2009 at 7:23 PM

Shakti,

I forgot to add the  declarations part of the Webservice.

  <PointF> is a structure that comes from using System.Drawing.  Basically a X,Y ordered pair of points on a 2 dimensional system.  http://msdn.microsoft.com/en-us/library/system.drawing.pointf.aspx

 

using System;
using System.Net;
using System.Globalization;
using System.IO;
using SharpMap.Data.Providers;
using SharpMap.Data.Providers.ShapeFile;
using System.Collections.Generic;
using System.Drawing;
using SharpMap.Data;
using System.Data;
using System.Text;
using SharpMap.Geometries;

public class ShapefileReader
{
    /// <summary>
    /// This method parses an ESRI shapefile and returns a list of simple Shape objects
    /// </summary>
    /// <param name="filePath">Path to the ESRI shapefile (.shp)</param>
    /// <param name="classify">The attribute field to be sent back with each feature</param>
    /// <param name="filterColumn">The attribute upon which to filter geometry</param>
    /// <param name="filterValue">The value of the attribute to base the filter</param>
    /// <param name="cmd">The comparison operator for the filter value</param>
    /// <returns>A list of Shape object, where each Shape is a Shapefiles's part and the value of the
    /// attribue field</returns>
    ///
  
   bool proccessGeo = true;

    public List<Shape> LoadShapefileLayer(string filePath, string classify, string filterColumn, string filterValue, string cmd)
    {

 

Feb 24, 2009 at 12:51 PM
Hello Tkowal
Now I am facing error at                             layer.Add(new Shape(points, gClass));

The best overloaded method match for 'Shape.Shape(System.Collections.Generic.List<System.Drawing.PointF>, System.Drawing.Color)' has some invalid arguments  
Cannot convert from 'string' to 'System.Drawing.Color' 

Thanks
Shakti


Feb 24, 2009 at 3:50 PM
shakti,


I remember when I first used Juan D. webservice.  It was a real pain finding the correct references to use in the project. The references I am currently using are:

 

  • NPACK
  • SharpMap
  • System
  • System.Core
  • System.Data
  • System.Drawing
  • System.EnterpriseServices
  • System.Web.Services
  • System.Xml

I recieved similiar error messages when I translated the Webservice into VB.Net (My natural programming Language).  I could not resolve the issues so I re-did the service in Framework 3.5 using C#.  This was my first C application ever and it has been a real learning experience for me.  I am not well versed in C.  My success have stemmed from brute force trial and error with a little help for folks in this forum.  As such I would like to help others as they have done for me whenever I can.


I would be happy to send the complete project and solution to you that compiles on my end....  Let me know where I can send it or upload it to.  Be advised that i sit behind a firewall that filters out a lot of shared storage which limits where I can upload to.


Ted

Feb 24, 2009 at 4:00 PM
can you send me at my email shakti5385@yahoo.co.in
Thanks
Shakti
Feb 24, 2009 at 4:02 PM
can you send me at my email shakti5385@yahoo.co.in
Thanks
Shakti
Feb 24, 2009 at 4:28 PM
It is on its way!  Good Luck
Feb 24, 2009 at 6:28 PM
HAVE n't received any email yet
Mar 5, 2009 at 4:04 PM
Hello tkowal can you please send me email, I haven't received your email.  please use my email shakti5385@yahoo.co.in

thanks
Mar 5, 2009 at 6:03 PM

It keeps getting returned? If you get this please reply then I will reply with the Web Service Code

Ted

Thaddeus S. Kowal
Asset Management/GIS

HNTB Corporation
8700 West Flagler Street
Suite 200
Miami, Florida 33174-2428

Tel (305) 551-8100
Fax (305) 551-2800

-----Original Message-----
From: shakti5385 [mailto:notifications@codeplex.com]
Sent: Thursday, March 05, 2009 11:05 AM
To: Thaddeus Kowal
Subject: Re: SharpMap in Virtual Earth [SharpMap:47712]

From: shakti5385

Hello tkowal can you please send me email, I haven't received your email. please use my email shakti5385@yahoo.co.in

thanks

Read the full discussion online.

To add a post to this discussion, reply to this email (SharpMap@discussions.codeplex.com)

To start a new discussion for this project, email SharpMap@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

This e-mail and any files transmitted with it are confidential and are intended solely for the use of the individual or entity to whom they are addressed. If you are NOT the intended recipient or the person responsible for delivering the e-mail to the intended recipient, be advised that you have received this e-mail in error and that any use, dissemination, forwarding, printing or copying this e-mail is strictly prohibited.

Mar 5, 2009 at 8:45 PM
Please send me at my official email
shakti.dulawat@accumatch.com

let me also know that what you used v0.9 or v2

thanks
shakti


Mar 6, 2009 at 3:17 PM
I just resent it.

Good Luck
Mar 11, 2009 at 11:11 PM
Edited Mar 12, 2009 at 12:02 AM

Hi John,

Shakti and I are still trying to display our own shape files in VirtualEarth., using the latest trunk of v2.0. They are in the state plane projection/coordinate system. We modified some of Juan DoNeblo's code and included a snippet below. It's a simplified version of the ShapeFileReader.cs class. We're opening our source shape file, converting the projection system from state plane to WGS 84 using wkt files, and then using an IFeatureDataReader to read through the file. We retrieve coordinates from each Geometry object and convert those into Points. We then turn the Points into Shapes and add the Shapes to the layer. To refresh your memory this is the project that starts up with a VE map centered on Great Britain, and asks you to select an overlay. We replaced the values in the drop-down with our own shape files. Everything is running and it appears to be returning a layer to VE, but VE just sits there with an error message saying "Please wait while retrieving ShapeFile data" but never paints the shapes on the map.

Could I send you my shape files to see if you can get them to display in v2?

Thanks,
Brad
--------------------------------------------

using System;
using System.Net;
using System.Globalization;
using System.IO;
using SharpMap.Data.Providers.ShapeFile;
using System.Collections.Generic;
using System.Drawing;
using SharpMap.Data;
using SharpMap.Expressions;
using System.Data;
using System.Text;
using GeoAPI.Geometries;
using GeoAPI.Coordinates;
using GeoAPI.CoordinateSystems;
using GeoAPI.CoordinateSystems.Transformations;
using GisSharpBlog.NetTopologySuite.Geometries;
using SharpMap.Utilities;
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;
using NetTopologySuite.Coordinates;
using NPack.Interfaces;

public class ShapefileReader
{
    /// <summary>
    /// This method parses an ESRI shapefile and returns a list of simple Shape objects
    /// </summary>
    /// <param name="filePath">Path to the ESRI shapefile (.shp)</param>
    /// <returns>A list of Shape object, where each Shape is a Shapefiles's part</returns>
    public List<Shape> LoadShapefileLayer(string filePath)
    {
        Random random = new Random((int)DateTime.Now.Ticks);
        // SharpMap's Shapefile reader / writer
        ShapeFileProvider sf = null;

        try
        {
            GeometryServices gs = new GeometryServices();
            sf = new ShapeFileProvider(filePath, gs.DefaultGeometryFactory,     
                gs.CoordinateSystemFactory);
            sf.Open(true);

            ICoordinateSystem srs = gs.CoordinateSystemFactory.CreateFromWkt(sf.SpatialReference.Wkt);

            ICoordinateSystem wgs84 = gs.CoordinateSystemFactory.CreateFromWkt("GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]]");

            ICoordinateTransformation ics = gs.CoordinateTransformationFactory.CreateFromCoordinateSystems(srs, wgs84);
            sf.CoordinateTransformation = ics;
            if (sf.ShapeType != ShapeType.Polygon)
                return null;
            IFeatureDataReader ifdr = sf.GetReader();

            List<Shape> layer = new List<Shape>();
            IGeometry geom;
      
            while (ifdr.Read())
            {
                geom = ifdr.Geometry;

                BufferedCoordinateSequence bcs = (BufferedCoordinateSequence)geom.Coordinates;

                List<PointF> points = new List<PointF>();
                for (int a = 0; a < bcs.Count; a++)
                {
                    double X = bcs[a].X;
                    double Y = bcs[a].Y;
                    points.Add(new PointF((float)X, (float)Y));
                    Color randomColour = Color.Green;
                    layer.Add(new Shape(points, randomColour));
                }
            }          

            return layer;

        }
        finally
        {
            if (sf != null)
                sf.Close();
        }
    }

}

/// <summary>
/// A simple Shape class. Contains information about the shape's vertices and colour
/// </summary>
public class Shape
{
    public List<PointF> Points { get; set; }
    public Color Colour { get; set; }

    public Shape(List<PointF> points, Color colour)
    {
        this.Points = points;
        this.Colour = colour;
    }
    public Shape()
    {

    }
}

Coordinator
Mar 12, 2009 at 11:11 AM
Hi Brad, to start with I would set a break point at the 'return layer' line and make sure it is being hit.
Also check the IIS event logs and Windows Event Viewer and see if the request is a) being recieved b) completing successfully
You could also use the net tab of Firebug to check this (fantastic FireFox plugin)
Also perhaps put the catch block into the try statement and seeing if you end up in there and if so why.
You can check if v2 can render the shapefile by opening it up in the winforms demo project included with v2.

If all the above seems ok then the issue is with the VE SDK/client javascript ..

If you still want to mail me the shapefile m me and i will reply.. hth jd
Mar 12, 2009 at 3:00 PM

Hi John, I will check these things out and let you know if I need more help.

Thanks!

Brad Martin

Accumatch

214-823-5579 Ext. 120

www.accumatch.com

From: johndiss [mailto:notifications@codeplex.com]
Sent: Thursday, March 12, 2009 4:11 AM
To: brad.martin@accumatch.com
Subject: Re: SharpMap in Virtual Earth [SharpMap:47712]

From: johndiss

Hi Brad, to start with I would set a break point at the 'return layer' line and make sure it is being hit.
Also check the IIS event logs and Windows Event Viewer and see if the request is a) being recieved b) completing successfully
You could also use the net tab of Firebug to check this (fantastic FireFox plugin)
Also perhaps put the catch block into the try statement and seeing if you end up in there and if so why.
You can check if v2 can render the shapefile by opening it up in the winforms demo project included with v2.

If all the above seems ok then the issue is with the VE SDK/client javascript ..

If you still want to mail me the shapefile m me and i will reply.. hth jd

Read the full discussion online.

To add a post to this discussion, reply to this email (SharpMap@discussions.codeplex.com)

To start a new discussion for this project, email SharpMap@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Mar 12, 2009 at 6:03 PM

Hi John, we were able to get our shapefiles to display. The problem was that this line:

 

                layer.Add(new Shape(points, Color.Green));


was inside our For loop instead of outside.

 

We need to modify some of the code in the QueryPoint() method so that we only display the shapes that fall within the bounding box. The original code from Juan DoNeblo doesn’t execute with v2. 
 

Thanks,

Brad

Mar 13, 2009 at 1:01 AM
Hi everyone, I have a large shapefile containing about 50,000 shapes. I want to display them in Virtual Earth, but only those that fall within my BoundingBox, say 100 to 200 at a time. Can someone point me to some sample code that runs in the latest v2 SVN trunk that will retrieve only those shapes and not all 50,000?

Thanks,
Brad
Coordinator
Mar 13, 2009 at 9:28 AM
Hi Brad,

instead of
IFeatureDataReader ifdr = sf.GetReader();

try using
IFeatureDataReader ifdr = sf.ExecuteFeatureQuery( SharpMap.Expressions.FeatureQueryExpression.Intersects(bbox.Extents) );

Hth FObermaier
Mar 16, 2009 at 4:11 PM

Hth, Do you have an example of passing the Bounding Box parameter?

From: fobermaier [mailto:notifications@codeplex.com]
Sent: Friday, March 13, 2009 2:28 AM
To: brad.martin@accumatch.com
Subject: Re: SharpMap in Virtual Earth [SharpMap:47712]

From: fobermaier

Hi Brad,

instead of
IFeatureDataReader ifdr = sf.GetReader();

try using
IFeatureDataReader ifdr = sf.ExecuteFeatureQuery( SharpMap.Expressions.FeatureQueryExpression.Intersects(bbox.Extents) );

Hth FObermaier

Read the full discussion online.

To add a post to this discussion, reply to this email (SharpMap@discussions.codeplex.com)

To start a new discussion for this project, email SharpMap@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Mar 16, 2009 at 5:24 PM
Hi Brad

use the ShapeFileProviders GeometryFactory to create the GeoApi.Geometries.IExtent2d Extent for your query.
The call should be something like this:
prov.GeometryFactory.CreateExtents2D( ... )
hth
FObermaier
Mar 16, 2009 at 5:27 PM

Don’t I need to pass in a bounding box from the client?

From: fobermaier [mailto:notifications@codeplex.com]
Sent: Monday, March 16, 2009 10:25 AM
To: brad.martin@accumatch.com
Subject: Re: SharpMap in Virtual Earth [SharpMap:47712]

From: fobermaier

Hi Brad

use the ShapeFileProviders GeometryFactory to create the GeoApi.Geometries.IExtent2d Extent for your query.
The call should be something like this:

prov.GeometryFactory.CreateExtents2D( ... )

hth
FObermaier

Read the full discussion online.

To add a post to this discussion, reply to this email (SharpMap@discussions.codeplex.com)

To start a new discussion for this project, email SharpMap@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Mar 16, 2009 at 7:07 PM
Hi Brad, typically you will retrieve the necessary values from the client (via query string or form values) and then use them to create the IExtents2D object hth jd
Mar 16, 2009 at 8:36 PM

 

 

John/FObermaier, I've managed to pass in the bounding box rectangle from VirtualEarth via JavaScript, and so far have this code below. How do I get from my IExtents2D rect object to bbox.Extents ? I don't see an Extents property of my rect object, or any other property that returns an IExtent object.

sf =

new ShapeFileProvider(filePath, gs.DefaultGeometryFactory, gs.CoordinateSystemFactory);
sf.Open(
true);
IExtents2D

rect = sf.GeometryFactory.CreateExtents2D(Double.Parse(topLeftLong),Double.Parse(topLeftLat), Double.Parse(botRightLong), Double.Parse(botRightLat));

 

IFeatureDataReader

ifdr = sf.ExecuteFeatureQuery(FeatureQueryExpression.Intersects(bbox.Extents);   <-- there is no rect.Extents property

Thx,
Brad

Mar 16, 2009 at 8:44 PM
I think I figured that last one out. IExtents2D implements IExtents so using passing the rect object by itself seems to work. Thx
Mar 16, 2009 at 9:37 PM
Edited Mar 16, 2009 at 9:42 PM

My intersection query is not returning any rows. My basic sf.GetReader() code works fine and displays all my shapes onPageLoad without having to pan the map. Does it look like I'm missing anything? Am I correct in assuming that:
XMin = bottom Right Long
YMin = bottom Lat
XMax = top Left Long
YMax = top Lat
?
Thx,
Brad
-------------------------------------------------

rect = sf.GeometryFactory.CreateExtents2D(

Double.Parse(botRightLong), Double.Parse(botRightLat),
    
Double.Parse(topLeftLong), Double.Parse(topLeftLat));

 

List<Shape> layer = new List<Shape>();
IGeometry geom; 
while (ifdr.Read())

geom = ifdr.Geometry;
BufferedCoordinateSequence bcs = (BufferedCoordinateSequence)geom.Coordinates; 
List<PointF> points = new List<PointF>(); 
for (int a = 0; a < bcs.Count; a++)

double X = bcs[a].X; 
double Y = bcs[a].Y; 
points.Add(
new PointF((float)X, (float)Y)); 
}
layer.Add(
new Shape(points, Color.FromArgb(75,0,128,0))); 
}
return layer;

 

 

 

 

 

 

 

Coordinator
Mar 17, 2009 at 9:21 AM
Hi Brad,
the values for your bounding box match the coordinates of your shapefile? Maybe you need some transformation beforehand?
In your example i can't see the call sf.ExecuteFeatureQuery(...) to return the IFeatureDataReader.

FObermaier
Coordinator
Mar 17, 2009 at 1:09 PM
Hi Brad, I think you may have your left and right back to front: xmin should be bottom left.. hth jd
Mar 17, 2009 at 3:20 PM

Hi John, I tried switching the order of my extents again per your suggestion but still nothing. The shape file has 8 shapes in it. If I don't run the Intersection query, it enters the Read loop and the shapes display on my map. With the Intersection query it doesn't enter the loop. fobermaier asked if I was doing a transformation beforehand, which I am. The shapefile is converted to WGS84 before I execute my Intersection query. Here's what I've got so far. Any ideas? Thx, Brad
------------------------
            GeometryServices gs = new GeometryServices();
            sf = new ShapeFileProvider(filePath, gs.DefaultGeometryFactory, gs.CoordinateSystemFactory);
            sf.Open(true);
        
            ICoordinateSystem srs = gs.CoordinateSystemFactory.CreateFromWkt(sf.SpatialReference.Wkt);
            ICoordinateSystem wgs84 = gs.CoordinateSystemFactory.CreateFromWkt("GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]]");
            ICoordinateTransformation ics = gs.CoordinateTransformationFactory.CreateFromCoordinateSystems(srs, wgs84);
            sf.CoordinateTransformation = ics;
  //header of the ShapeFile shows these Extents after transformation:
  //{Extents [-98.0724046297028 - -96.3672176811281, 31.5900876676805 - 32.9861508519606]}

            IExtents2D rect2;
            IExtents rect;
      //tried Extents2D with these min/maxes but didn't work
    //my VE map extents are coming in as topLat,leftLong,botLat,rightLong
    //33.245578933385545,-98.54461669921876,31.85656420395222,-96.34735107421875  

            rect2 = sf.GeometryFactory.CreateExtents2D(Double.Parse(leftLong),
                Double.Parse(botLat), Double.Parse(rightLong), Double.Parse(topLat));
  //I'm hard-coding the extents of my VE map for now to make testing easier. 
            ICoordinate minLatLong = sf.GeometryFactory.CoordinateFactory.Create(-101, 29);
            ICoordinate maxLatLong = sf.GeometryFactory.CoordinateFactory.Create(-93, 35);

  //tried switching to IExtents but still not working
            rect = sf.GeometryFactory.CreateExtents(minLatLong, maxLatLong);
            FeatureQueryExpression query = FeatureQueryExpression.Intersects(rect);
           
            if (sf.ShapeType != ShapeType.Polygon)
                return null;

            IFeatureDataReader ifdr = sf.ExecuteFeatureQuery(query);
           
            List<Shape> layer = new List<Shape>();
            IGeometry geom;
           
            while (ifdr.Read())
            {
                geom = ifdr.Geometry;
                BufferedCoordinateSequence bcs = (BufferedCoordinateSequence)geom.Coordinates;
                List<PointF> points = new List<PointF>();
                for (int a = 0; a < bcs.Count; a++)
                {
                    double X = bcs[a].X;
                    double Y = bcs[a].Y;
                    points.Add(new PointF((float)X, (float)Y));
                }
                layer.Add(new Shape(points, Color.FromArgb(75,0,128,0)));
            }
            return layer;

Coordinator
Mar 17, 2009 at 4:06 PM
Edited Mar 17, 2009 at 4:08 PM
I think you may need to massage your bounds into the 0 to 360 range.. hth jd
Mar 17, 2009 at 4:54 PM
Both my Virtual Earth bounds and my shapefile bounds appear to be -180 to 180. You think they need to be converted?
Coordinator
Mar 17, 2009 at 5:01 PM
no sorry.. I had misread the extents..
Coordinator
Mar 17, 2009 at 9:57 PM
Hi Brad,
I think using the GeometryFactory of the ShapefileProvider is the problem.
Assigning a CoordinateTransformation to ShapefileProvider does not change
the SpatialReferenceSystem of GeometryFactory.

Try using a GeometryFactory with VE SpatialReference System, something like
var gfVE = gs[4326];
, and use that for building the extent:
rect2 = gfVE.CreateExtents2D(Double.Parse(leftLong), Double.Parse(botLat),
 Double.Parse(rightLong), Double.Parse(topLat));
Hth
FObermaier
Mar 18, 2009 at 3:25 AM

Hi fobermaier, I tried what you said and am getting an "Object reference not set to an instance of an object" error on the line where it executes the intersection query. It's occuring at SharpMap.Data.Providers.FeatureProviderBase.transformQuery(FeatureQueryExpression query):

        private FeatureQueryExpression transformQuery(FeatureQueryExpression query)
        {
            SpatialBinaryExpression spatial = query.SpatialPredicate;

            //the SpatialReference property is null
            ICoordinateSystem querySpatialReference = spatial.SpatialExpression.SpatialReference;

            //exception thrown on this line
            if (querySpatialReference.EqualParams(SpatialReference))
            {
                return query;
            }
        ...

Is my code below what you had in mind?

Thanks, 
Brad
-------------------------
            GeometryServices gs = new GeometryServices();
           
            sf = new ShapeFileProvider(filePath, gs.DefaultGeometryFactory, gs.CoordinateSystemFactory);
            sf.Open(true);
           
            ICoordinateSystem srs = gs.CoordinateSystemFactory.CreateFromWkt(sf.SpatialReference.Wkt);
            ICoordinateSystem wgs84 = gs.CoordinateSystemFactory.CreateFromWkt("GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]]");
            ICoordinateTransformation ics = gs.CoordinateTransformationFactory.CreateFromCoordinateSystems(srs, wgs84);
            sf.CoordinateTransformation = ics;
            IExtents2D rect2;
            IExtents rect;
            IGeometryFactory gfVE = gs["4326"];
           
            minLatLong = gfVE.CoordinateFactory.Create(-101, 29);
            maxLatLong = gfVE.CoordinateFactory.Create(-93, 35);
            rect2 = gfVE.CreateExtents2D(Double.Parse(leftLong),
                Double.Parse(botLat), Double.Parse(rightLong), Double.Parse(topLat));
            FeatureQueryExpression query = FeatureQueryExpression.Intersects(rect2);
           
            if (sf.ShapeType != ShapeType.Polygon)
                return null;

        //"Object reference not set to an instance of an object" error on this line    
        IFeatureDataReader ifdr = sf.ExecuteFeatureQuery(query);           
           
            List<Shape> layer = new List<Shape>();
            IGeometry geom;
           
            while (ifdr.Read())
            {
                geom = ifdr.Geometry;
                BufferedCoordinateSequence bcs = (BufferedCoordinateSequence)geom.Coordinates;
                List<PointF> points = new List<PointF>();
                for (int a = 0; a < bcs.Count; a++)
                {
                    double X = bcs[a].X;
                    double Y = bcs[a].Y;
                    points.Add(new PointF((float)X, (float)Y));
                }
                layer.Add(new Shape(points, Color.FromArgb(75,0,128,0)));
            }
            return layer;

Coordinator
Mar 18, 2009 at 10:13 AM
Hi Brad,

sorry that was my mistake. It should have ben
var gfVE = gs["EPSG:4326"]; 
That way you have a valid SpatialReference. Could you provide the
OriginalSpatialReference property of the ShapefileProvider and the
SpatialReference property of the ShapeFileProviders GeometryFactory?
Or better a sample shapefile?

Hth FObermaier
Coordinator
Mar 18, 2009 at 11:26 AM
You may also have to make sure the SridMap has been initialized (this should happen exactly once per application) so you could do it either in a static initializer in global.asax or a static initializer in the webservice itself
It would look something like:
    SridMap.DefaultInstance = new SridMap(new[] { new SridProj4Strategy(0, new GeometryServices().CoordinateSystemFactory) });

this will likely change when a more suitable system is devised.. hth jd
Mar 18, 2009 at 4:07 PM
Hi John, I had included the very code you mention above but did not paste it into the window yesterday. It's not throwing any errors.

Hi Fobermaier, I'm still getting the same exception as before ("Object reference not set to an instance of an object"), now on this line in the FeatureProviderBase.cs.:
                
                IExtents transformed = CoordinateTransformation.InverseTransform(spatial.SpatialExpression.Extents,
                                                                                 GeometryFactory);
When the exception is thrown, immediately before IExtents transformed is assigned a value...
The spatial reference property of SpatialExpression is:

{GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84", 6378137, 298.257223563, AUTHORITY["EPSG", "7030"]], TOWGS84[0, 0, 0, 0, 0, 0, 0], AUTHORITY["EPSG", "6326"]], PRIMEM["Greenwich", 0, AUTHORITY["EPSG", "8901"]], UNIT["degree", 0.0174532925199433, AUTHORITY["EPSG", "9122"]], AUTHORITY["EPSG", "4326"]]}

And the SpatialReference property of GeometryFactory is:

{GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137, 298.257223563]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]}

------
The .wkt for my shapefile has this string:
PROJCS["NAD_1983_StatePlane_Texas_North_Central_FIPS_4202_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["False_Northing",6561666.666666666],PARAMETER["Central_Meridian",-98.5],PARAMETER["Standard_Parallel_1",32.13333333333333],PARAMETER["Standard_Parallel_2",33.96666666666667],PARAMETER["Latitude_Of_Origin",31.66666666666667],UNIT["Foot_US",0.3048006096012192]]

The spatial reference property of the ShapeFileProvider GeometryFactory (before I do the Coordinate System Transformation) is:
PROJCS["NAD_1983_StatePlane_Texas_North_Central_FIPS_4202_Feet", GEOGCS["GCS_North_American_1983", DATUM["D_North_American_1983", SPHEROID["GRS_1980", 6378137, 298.257222101]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]], PROJECTION["Lambert_Conformal_Conic"], PARAMETER["False_Easting", 1968500], PARAMETER["False_Northing", 6561666.66666667], PARAMETER["Central_Meridian", -98.5], PARAMETER["Standard_Parallel_1", 32.1333333333333], PARAMETER["Standard_Parallel_2", 33.9666666666667], PARAMETER["Latitude_Of_Origin", 31.6666666666667], UNIT["Foot_US", 0.304800609601219]] 

They are the same, as you'd expect, right?

The spatial reference property of my ShapeFileProvider GeometryFactory after the Coordinate System Transformation is:
{GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137, 298.257223563]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]}

I'd be happy to send you my shapefile. Please give me your e-mail if you want to see it.

Thanks for your time,
Brad
 

Coordinator
Mar 18, 2009 at 9:23 PM
Hi Brad,

after doing some testing with the SRSs you specified, I think the problem is,
that GeographicTransform is only a stub in Proj.Net and thus cannot convert
from WGS84 to the SRS of your Shapefile.
The reason that GetReader() is doing the job is that it passes the 'untransformed'
bounds of your shapefile.

To get around this, you may test the extent of each geometry your reader returns
against your viewport and omit the ones unnecessary.

Hth FObermaier

Mar 18, 2009 at 10:06 PM
Edited Mar 19, 2009 at 12:22 AM

Hi FObermaier,

I am converting from my shapefile SRS to WGS 84 before the intersection query is executed, successfully I think. Before coding the Coordinate System transformation I wasn't able to view my shapes in VE at all. Now they display (though all at once unfortunately).

Is there some other transformation required for the intersection query, in addition to the one I'm already executing?

            //the Wkt contains the SRS of my shapefile
            ICoordinateSystem srs = gs.CoordinateSystemFactory.CreateFromWkt(sf.SpatialReference.Wkt);
            //this is the WGS84 SRS

            ICoordinateSystem wgs84 = gs.CoordinateSystemFactory.CreateFromWkt("
GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]]");
            ICoordinateTransformation ics = gs.CoordinateTransformationFactory.CreateFromCoordinateSystems(srs, wgs84);
            sf.CoordinateTransformation = ics;

I'll try your workaround suggestion.

Thanks for trying FObermaier,
Brad

Coordinator
Mar 18, 2009 at 11:07 PM
Hi Brad,
for the intersection query to perform, the chosen viewport needs to be converted back to the original srs of the shapefile.
That should be done automatically but it fails because the geographic transform is not implemented in proj.net (Maybe
there are other things missing, too).

Hth FObermaier
Mar 19, 2009 at 12:27 AM
Hi FObermaier,

Our next step after getting this working was to load the data into SQL Server anyway, in WGS84 SRS. If I can get this workaround working as a proof of concept more or less, I think I'll move ahead with the SQL Server part and not worry about the intersection query between different SRS's. 

Thanks for all your help,
Brad
May 18, 2010 at 8:03 PM

Hello,

I have shapefiles in NAD83 format and I am trign to plot the files on a bing map. I am trying to use JuanDoNeblo technique to plot the shape file. I understand that I need to first convert the shape file to WGS84 to plot it on a bing map. I am trying to use the code that is posted by BradMartin with little luck. When I compile the code, it is failing at the line marked red. Here is the compilation error.

Error 1 Cannot implicitly convert type 'ProjNet.CoordinateSystems.Transformations.ICoordinateTransformation' to 'SharpMap.CoordinateSystems.Transformations.ICoordinateTransformation'. An explicit conversion exists (are you missing a cast?) 

Any help is appreciated. Thanks.

using System;
using System.Net;
using System.Globalization;
using System.IO;
using SharpMap.Data.Providers.ShapeFile;
using System.Collections.Generic;
using System.Drawing;
using SharpMap.Data;
using SharpMap.Expressions;
using System.Data;
using System.Text;
using SharpMap.Geometries;
using SharpMap.Utilities;
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;
using NPack.Interfaces;

 

public class ShapefileReader
{
    /// <summary>
    /// This method parses an ESRI shapefile and returns a list of simple Shape objects
    /// </summary>
    /// <param name="filePath">Path to the ESRI shapefile (.shp)</param>
    /// <returns>A list of Shape object, where each Shape is a Shapefiles's part</returns>
    public List<Shape> LoadShapefileLayer(string filePath)
    {
        Random random = new Random((int)DateTime.Now.Ticks);
        // SharpMap's Shapefile reader / writer
        ShapeFileProvider sf = null;
        try
        {
        
            sf = new ShapeFileProvider(filePath);
            sf.Open(true);

            CoordinateSystemFactory csf = new CoordinateSystemFactory();
            CoordinateTransformationFactory ctf = new CoordinateTransformationFactory();

            ICoordinateSystem srs = csf.CreateFromWkt(sf.SpatialReference.Wkt);

            ICoordinateSystem wgs84 = csf.CreateFromWkt("GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]]");

            ICoordinateTransformation ics = ctf.CreateFromCoordinateSystems(srs, wgs84);
            
            sf.CoordinateTransformation = ics;

         
            if (sf.ShapeType != ShapeType.Polygon)
                return null;

May 18, 2010 at 8:17 PM

 Moonwalk, what version of SharpMap are you using? I'm running v2.0, several things changed from version 1. The error you're getting might be related to your version. My code looks similar to yours, with one minor difference below.

<font size="2">

 

</font>GeometryServices gs = new GeometryServices();

 ICoordinateTransformation ics = gs.CoordinateTransformationFactory.CreateFromCoordinateSystems(srs, wgs84);

 sf.CoordinateTransformation = ics;

 

Brad

May 18, 2010 at 9:11 PM

I am using SharpMap2.0(The description says SharpMap v2.0 Beta1) . Not sure where I downloaded it from. I didnot use Geometry services. All I am doign is take the sahpe file, convert the coordiante system and dispaly it on a bing map. I have a very little understanding of sharpmap dll. Do I need to use GeometryServices in my code? and what dll should I reference to use that?

Thanks.

Coordinator
May 19, 2010 at 10:36 AM

Hi moonwalk, you should get the v2 code from http://sharpmapv2.googlecode.com . To overlay on Bing maps you need to convert to Web /Pseudo  Mercator  (EPSG:3857) _not_ WGS 84

hth jd

May 19, 2010 at 3:09 PM

That link is taking me back to codeplex. and here is what is available for the download on that page. SharpMap-0.9-Trunk-2009.10.22.

Do you have a smaple code for that converison?

Thanks.

May 19, 2010 at 6:56 PM

John,

I looked at the discussions that are posted on the website and here is what I have gathered so far. To be able to plot a shape file that is in the NAD83 coordinate system on a bing map, it is a two step process. First, it needs to be converted to WGS84 and then convert it to Mercator? Is that right?

 

Coordinator
May 19, 2010 at 7:45 PM
Edited May 20, 2010 at 8:53 AM

Hi moonwalk,

to use sharpmapv2 you need to get the sourcecode with some subversion client (svn, tortoisesvn, ...)

the url for the source is http://sharpmapv2.googlecode.com/svn/trunk/

hth FObermaier