SharpMap integration question

Sep 20, 2009 at 7:14 PM

Hi,

In your roadmap picture, I see that you intend to integrate SharpMap. That would be great, since it has some features I need too (besides the features that you already have). Therefore I was wondering:

  • when do you plan to integrate it?
  • how do you plan to do it? Will it become another tile provider for BruTile?

Anything else that you would care to share.

Thanks and keep up the good work!

Erik

Sep 21, 2009 at 2:06 PM
Edited Sep 21, 2009 at 2:17 PM

Hi Erik,

How: Exactly. In my local proof of concept I implemented a SharpMapTileProvider derived from ITileProvider. I had to make some modifications to the SharpMap code (I'll post below).

When: I don't want to promise anything regarding planning. I now have more projects using BruTile so I expect an increase in the amount of time I can spend on it. What I will work on will depend on the requirements of the projects.

Other: In my local proof of concept SharpMap is just a TileProvider for BruTile but for SharpMap users the tiling concept is of little concern. Therefore I am also looking at an implementation where the BruTile caching mechanism is hidden in some kind of renderer separated from the rest of the SharpMap client code. This will need some modifications in SharpMap and will take more time to complete.

btw, which platform are you using? You should be aware that compact framework needs a port of SharpMap, and for the Silverlight port SharpMaps gdi+ renderer should be replaced with some alternative raster renderer.

Paul

Sep 21, 2009 at 2:14 PM

Here is my SharpMapTileProvider.cs:

using SharpMap;
using SharpMap.Data.Providers;
using SharpMap.Geometries;
using SharpMap.Layers;
using SharpMap.Styles;
using Tiling;

namespace VectorTileProvider
{
  public class SharpMapTileProvider : ITileProvider
  {
    #region ITileProvider Members

    Map map;
    object syncRoot = new object();


    public SharpMapTileProvider()
    {
      map = new Map(256, 256);
      VectorLayer vectorLayer = new VectorLayer("myshapelayer");
      VectorStyle style = new VectorStyle();
      vectorLayer.Style = style;
      ShapeFile shapeFile = new ShapeFile(GetAppDir() + "\\SampleGeoData\\countries.shp");
      shapeFile.Open();
      vectorLayer.DataSource = shapeFile;

      map.Layers.Add(vectorLayer);

      string relativePath = "SampleGeoData/GeoTiff/";

      SharpMap.Layers.GdalRasterLayer layer;
      layer = new SharpMap.Layers.GdalRasterLayer("GeoTiffA", relativePath + "LandUse_view10.tif");
    }

    public byte[] GetTile(TileInfo tileInfo)
    {
      lock (syncRoot)
      {
        Extent extent = tileInfo.Extent;
        map.ZoomToBox(new BoundingBox(extent.MinX, extent.MinY, extent.MaxX, extent.MaxY));
        return map.GetMapAsByteArray();
      }
    }

    private static string GetAppDir()
    {
      return System.IO.Path.GetDirectoryName(
        System.Reflection.Assembly.GetEntryAssembly().GetModules()[0].FullyQualifiedName);
    }

    #endregion
  }
}

Here the config I used. The data used is included in the SharpMap samples:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tiling;

namespace BruTileDemo
{
  class ConfigShapefile : IConfig
  {
    string format = "jpg";
    string name = "Shapefile";
    
    private static double[] resolutions = new double[] { 
      0.70312500000000000000, 0.35156250000000000000, 0.17578125000000000000, 0.08789062500000000000,
      0.04394531250000000000, 0.02197265625000000000, 0.01098632812500000000, 0.00549316406250000000,
      0.00274658203125000000, 0.00137329101562500000, 0.00068664550781250000, 0.00034332275390625000,
      0.00017166137695312500, 0.00008583068847656250, 0.00004291534423828125, 0.00002145767211914062,
      0.00001072883605957031, 0.00000536441802978516, 0.00000268220901489258, 0.00000134110450744629};

    #region IConfig Members

    public Tiling.ITileCache<byte[]> FileCache
    {
      get
      {
        return null;
      }
    }

    public Tiling.IRequestBuilder RequestBuilder
    {
      get
      {
        return null;
      }
    }

    public Tiling.ITileSchema TileSchema
    {
      get
      {
        TileSchema schema = new TileSchema();
        foreach (double resolution in resolutions) schema.Resolutions.Add(resolution);
        schema.Height = 256;
        schema.Width = 256;
        schema.Extent = new Extent(-180, -90, 180, 90);
        schema.OriginX = -180;
        schema.OriginY = -90;
        schema.Name = name;
        schema.Format = format;
        return schema;
      }
    }

    #endregion

  }
}

Here are the methods added to SharpMaps Map.cs:

 

    public Map(int width, int heigth)
      : this(new System.Drawing.Size(width, heigth))
    {
    }

    public byte[] GetMapAsByteArray()
    {
      Image image = GetMap();
      MemoryStream memoryStream = new MemoryStream();
      image.Save(memoryStream, ImageFormat.Png);
      return memoryStream.ToArray();
    }

It needs these usings:

 

using System.Drawing;
using System.IO;
using System.Drawing.Imaging;

 

 

 

Sep 21, 2009 at 3:05 PM
Edited Sep 21, 2009 at 3:38 PM

Hi Paul,

Thanks for the quick reply!

It's most likely going to remain a desktop WPF application, and the specific features that I need from SharpMap is capability to import ESRI shape files, as well as DEM (Digital Elevation Maps). Basically, I want to create a scenario editor with a map, either provided as a 'map'' or using a tile provider. BTW, do you currently use a new project for this as part of your solution, since I don't see the VectorTileProvider namespace anywhere in your current code? And what about the "using Tiling" namespace - where does it come from? Where does that And I'm assuming you are still using v1 of SharpMap, and not the v2 branch that's under development?

Thanks,

Erik

Sep 21, 2009 at 5:14 PM
Edited Sep 21, 2009 at 5:30 PM

You will have no problems with WPF.

VectorTileProvider is the name of the assembly/namespace where the SharpMapTileProvider was in. You can simply delete the using.

The POC comes from an old project. The 'Tiling' namespace is now renamed to 'BruTile'.

I used V1 yes. I have not implemented it for V2, but it is on my todo list. With both version supported we could also lay V1 and V2 layers over each other. It would be great if this could close the gap between the two versions.

Paul.

Nov 12, 2009 at 9:37 AM

Hi Paul,

I visited your website and after being impressed by the demo Martijn gave, I had a closer look at BruTile. And really it looks great (good quality and fast)!

As I want to create territory maps based a.o. on ESRI shapefiles and Lat/Long markers I'm thinking of using SharpMap and BruTile for a desktop environment (WinForms or WPF). Basically the same concept as Erik described.

Have you made any progress using SharpMap and if so do you have an example demonstrating it?

Keep up the good work,

Frank

BTW I also posted this message in SharpMap (http://sharpmap.codeplex.com/Thread/View.aspx?ThreadId=72628)

 

Nov 14, 2009 at 10:10 AM
Edited Nov 14, 2009 at 10:12 AM

Hi Frank,

I had seen your post on the SharpMap forum earlier but I didnt want reply with another promise. So I committed a sample of the SharpMapTileProvider today. It is in the BruTileWpf project. The provider should also work in the WinForms and Surface projects. For CF you need a CF port of SharpMap, I think there are some around. For Silverlight you need a Silverlight version of SharpMap. This is more work because it will need a new renderer.  For what platform will you be using it?

The sample uses SharpMapV1 change set 60134 with the changes mentioned in the post above (the last part on Map.cs). I would also like to create a SharpMapV2 tile provider. It isy possible to combine multiple SharpMap layers in one tile (as in the sample), but it is not possible to yet to combine brutile layers. If you want tiles in the background you could use the Tile layer that is part of SharpMap. It is a precursor of BruTile. That SharpMap tile layer should be rewritten to use BruTile, but I probably wont get to that soon. 

For what do you want to use it? (just curious)

bye, Paul

Nov 14, 2009 at 3:22 PM

Hi Paul,

Basically I want to show where sales points are located and group them per area. Currently my project is in .Net Framework v2.0, but should be portable to WPF (with however some WinForms in it). I created a test project using a component called GMap that is a almost perfect for me. I demonstrated markers, small pie/bar charts per marker. It can also use layers on that you can draw on yourself and has plenty of tile providers. But for the territory part I don't know how to deal with easily.

Currently we use MapInfo that requires specially trained persons and is not so dynamic. But I have lots of administrative region shapefiles; like postal code areas, provinces and countries. With GMap I can create areas based on points (lat/long), but not the (thematic) options of SharpMap.

So that is why I looked at your component, the combination of a good "background" tile and SharpMap for the data visualisation. I can try to download the OpenStreetMap database and use that in SharpMap, but I prefer your approach. But as you mention a layer combination is currently not possible, so I have to wait or use GMap.

Have a nice weekend,

Frank

Nov 14, 2009 at 5:54 PM

Hi Frank,

Well it is possible to combine it with the WMS-C tile layer in SharpMap. See the sample here:

http://sharpmap.codeplex.com/SourceControl/changeset/view/60134#739068

But you need to find an OSM server that supports the WMS-C protocol.

Paul