ThinkGeo.com    |     Blog    |     Wiki    |     Support

Programmatically create a marker layer that can export to shapefile

I am using WPF GIS Editor. I appear to be missing some vital information. I can programmatically create layers with markers in them that render in the correctly assigned geographic locations, but I need to:

  • Have my layer appear in the GIS Editor Layer List;
  • Be able to select my layer and export it to a shapefile.

I am missing something very basic about how to create “Nice” layers that the Editor recognizes.

Anyone have a pointer to a code sample that would show me what I’m missing?

TIA.

– Mike

Hi Mike,

I think you means this utility: https://github.com/ThinkGeo/MapSuiteGisEditor

Because the GisEditor is open source utility now, so we don’t have sample or guide about it, but I think you can find our old topics about it, maybe they are helpful: http://blog.thinkgeo.com/category/gis-editor/

If that’s not helpful and you cannot solve it by view the code, could you please describe your requirement more detail, for example a project file, the test data, and the steps for reproduce your problem. So we can learn more about it and see whether we can provide some suggestion.

Regards,

Ethan

Thanks for your help. My problem is that I use brute force sometimes, and while that “works”, it is not always the best solution nor the one that I really need. Here is what I have attempted:

SimpleMarkerOverlay pointOverlay = CurrentOverlays.PlottedMarkerOverlay;

Vertex v = proj4.ConvertToExternalProjection(lon, lat);
PointShape p = new PointShape(v);
Marker m = new Marker§;
pointOverlay.Markers.Add(m);
Map1.Refresh(pointOverlay);

I’ve actually subclassed the Marker class and added some things to it, but that’s another discussion and can wait until I get this issue addressed first.

In fact, I add several thousand markers at different locations before actually refreshing the Map, but that’s not important either. What IS important, is that this layer is NOT included in the displayed Layer List, and I need it to be displayed there so that I can export the layer with its contents to a shapefile using the built in functions of the Editor.

After looking at some code in that web site, even though it doesn’t directly answer my particular issue here, I am getting the feeling that I am missing quite a bit of prep for this layer that would make it recognizable to the system as a layer to be included in that list a suitable for export.

For example, I see the necessity for definition of column data, which I do not have here. I also see the DrawCore method for a pointstyle being overridden, and I am doing none of that, just including render information in my marker class. Clearly, I am not following the correct design pattern for the Editor to accept my data for inclusion into the Layer List.

Do you know of any SIMPLE examples that demonstrate how this can be done? Once I understand exactly what needs to be done, I can take it from there.

Thanks.

Hi Mike,

The GIS Editor utility provide visual operated interface to help user operate your data.

It looks you want to build a custom shape file, I think you need to create a new blank shape file feature layer at first, the column value is not necessary(This information is contained in the .dbf file). After it’s created, you should want to modify it in UI and saved your operation, that’s how to use it in GIS Editor.

If you want to build this file by code, you should want to use our API, our API also support save to shape file, you can find many information about that in this forum. If you met detail problem about our API please let us know.

The two samples contains the code to create a new shape file or update data in existing shape file, wish that’s helpful.

https://wiki.thinkgeo.com/wiki/source_code_desktopeditionsample_editgeometryofshapefile_cs_101021.zip
https://wiki.thinkgeo.com/wiki/source_code_serviceseditionsample_splitpolygonintogridbasedonarea_cs_120321.zip

We don’t know how to provide a sample about GIS Editor because it’s a standalone utility.

Regards,

Ethan

Thanks for your interest and assistance anyway. I was able to begin to resolve my problem using my usual brute force methods assisted by Divine inspiration.

By establishing the Editor UI workflow for creating a new empty shapefile point layer, I was able to locate the code at the highest level which performs that function in the Infrastructure project. Once that code was located, I was able to circumvent the UI completely, by “cherry-picking” (cut-n-paste for those who do not understand the metaphor) the code necessary for creating that layer and inserting it into the Editor layer list, and also that code in fact creates the shapefile on the local disk.

Next step is to locate the code that performs the editing by adding new plotted points to that layer. Tomorrow is another day. Today was very fruitful.

But thanks anyway.

Hi Mike,

It looks you found a way to go next stop, if you met any problem to let us know, we can discuss about it.

Regards,

Ethan

Next event - have a custom style (class) now showing on map, but want to export that layer to a shapefile. So far, only the Default Point style is being exported to the shape file. Is there a trick to this? Any sample code on how to export a custom point style to a shapefile?

Thanks.

Hi Mike,

I think you misunderstand the style about shape file, the shape file don’t contains style information.

When you expert the shape into shape file, it only saved the shape and column values information, but the style is in our code.

The next time you render the shape file, you looks it’s default style that’s because you set the default style when you redner it again.

You should want to save the custom style by your code, or you can use serialization to save it like this:

                    using System.Runtime.Serialization.Formatters.Binary;

                    TextStyle style = new TextStyle();
                    BinaryFormatter formatter = new BinaryFormatter();
                    MemoryStream stream = new MemoryStream();
                    formatter.Serialize(stream, style);

Wish that’s helpful.

Regards,

Ethan

I don’t want to store my layer in a project file, I want it to render correctly from the shapefile, if possible. There MUST be some way to do this.

Is there any way to subclass the shapefile loader so that my points render according to my specific runtime style class based on data stored in the columns? Any existing example would help. If necessary, I have no issues with creating a new shapefile class for this purpose. Just need a little push in the right direction.

Thanks.

Hi Mike,

I understand that, if you don’t want to save the style into standalone file, you can try to save it into column value(dbf file).

The code as below should be helpful:

            PointStyle style = PointStyles.Capital1;

        GeoSerializer s = new GeoSerializer(new XmlGeoSerializationFormatter());
        string styleString = s.Serialize(style);
                   
        Feature feature = new Feature(0, 0);
        feature.ColumnValues.Add("style", styleString);
        ShapeFileFeatureSource.CreateShapeFile(ShapeFileType.Point, "test.shp", new Collection<DbfColumn>() { new DbfColumn("style", DbfColumnType.Memo, 5000, 0) });
        ShapeFileFeatureSource testSource = new ShapeFileFeatureSource("test.shp", GeoFileReadWriteMode.ReadWrite);
        testSource.Open();
        testSource.BeginTransaction();
        testSource.AddFeature(feature);
        testSource.CommitTransaction();
        testSource.Close();
        
        ShapeFileFeatureLayer testLayer = new ShapeFileFeatureLayer("test.shp");
        testLayer.Open();
        Collection<Feature> features = testLayer.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns);
        Feature f = features[0];
        string restoreStyle = f.ColumnValues["style"];
        testLayer.Close();

        PointStyle tmpStyle = s.Deserialize(restoreStyle) as PointStyle;
        
        testLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = tmpStyle;
        testLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

Regards,

Ethan

Ethan, I really appreciate your efforts to assist me. Please allow me to more precisely state what my intentions are, as I don’t think your solution will help much.

My style is NOT a simple nor a known type. It’s nature is such that each individual feature in this layer will have a different appearance that depends on the data stored in the columns for that feature. The graphic will be drawn with a different color, size, fill, and base shape which is drawn from a class in the library. I assume that it must therefore be assigned as a Custom Style.

It starts like this:

class MyWellPointStyle : WellPointStyle
{

}

Various methods are overridden as normal, particularly the DrawCore method.

If I understand you correctly, this information cannot be recorded in the Point shapefile because the shapefile always uses the default simple point style. What this means is that my code MUST be assigned to the layer AFTER the shapefile is opened and processed into the FeatureLayer classes.

What I am searching for is an automated way to force the system to call my code or use my code, either during or after the initial load of the information from the shapefile. Do you see any way to do that nicely?

Thanks.

Exciting news…I have resolved all of my issues, it all now works correctly.

I have been working with the MapSuiteGisEditor, which we license in order to modify to suit our purposes.

I was doing a few things wrong and they all compounded to cause me to think that my layer was not being displayed at all, when in fact it was being displayed.

So I have figured out how to create shapefiles correctly, with correct projection, index, and data columns and so forth, and cause that layer to be correctly handled by the Editor Layer List, with my custom style class being called correctly and providing the preview icon and so forth. My major problem is that the Map display projection and extent were not being set correctly as my layer was being created, loaded with features, and displayed. That is all now fixed.

There is a bug I discovered in the Editor with regard to custom class provided DrawSampleCore override. Apparently, the zooming causes the icon to be updated and drawn correctly in the layer list entry, but if the edit function is turned on or off, it loses its mind a defaults to a circle with a line through it from lower left to upper right, the invalid image icon. Zooming in either direction fixes this. I may be motivated to fix this in my copy in my spare time if I ever find any.

But anyway, thanks for your patience and assistance. All is now well, and I’ve learned a great deal.

Cheers

Hi Mike,

Thanks for your update, I am glad to hear you solved your issues.

I am not online yesterday so I hadn’t reply your last update.

Any question please let us know, we are glad to help you on our products.

Regards,

Ethan