You never got back to me, but I ended up writing what you wanted in C#.
The import of shapefile is the easy part. The more interesting parts are the code to figure coordinate systems and draw the entities.
The thing is, dotspatial does not have an easy way to specify coord system by the "short name" like CA83-VIF.
You have to use something like Mapguide API from autodesk (free), get the number code, then feed into dotspatial.
Here is how I access the shapefile and its features, and get a simplified list of point and pline props.
You can adapt to getting text and other props of the featrures. I checked and the "gis data" is available in the feature, I just did not use it yet for anything.
//returns lists of (("point", color, width, coord)("polyline", color, width, coords)..)
public List<object> GetFromShpFile(string shpfname, string sourceSystem, string targetSystem, bool StartingProgress) {
if (StartingProgress) StartProgress("Reading Shapefile...", 2, true);
//make list of return objects
List<List<string>> retItems = new List<List<string>>();
try {
//get epsg codes
MgCoordinateSystemFactory coordSysFactory = new MgCoordinateSystemFactory();
string baseSysWkt = coordSysFactory.ConvertCoordinateSystemCodeToWkt(sourceSystem);
string targetSysWkt = coordSysFactory.ConvertCoordinateSystemCodeToWkt(targetSystem);
MgCoordinateSystem srcCs = coordSysFactory.Create(baseSysWkt);
MgCoordinateSystem dstCs = coordSysFactory.Create(targetSysWkt);
int srccode = srcCs.EpsgCode;
int tgtcode = dstCs.EpsgCode;
//now read into dotspacial
Shapefile sf = Shapefile.OpenFile(shpfname);
//look at sf.ProjectionString
if (!File.Exists(Path.GetDirectoryName(shpfname) + "\\" + Path.GetFileNameWithoutExtension(shpfname) + ".prj"))
sf.Projection = ProjectionInfo.FromEpsgCode(srccode);
sf.Reproject(ProjectionInfo.FromEpsgCode(tgtcode));
//loop through items
//will be DotSpatial.Topology.FeatureType. Line, Point, MultiPoint, Polygon, Unspecified
bool DoClose = false;
DoClose = DoProgress("Reading linework...", sf.Features.Count);
int index = 0;
int done = 0;
foreach (Feature ft in sf.Features) {
if (!DoClose) {
//message every 10 items
if (done == 9) {
DoClose = DoProgressBy("Reading linework...", index);
done = 0;
}
DotSpatial.Topology.FeatureType typ = ft.FeatureType;
string color = "";
string width = "";
if (typ == FeatureType.Line || typ == FeatureType.Polygon) {
//coords
StringBuilder coords = new StringBuilder("");
foreach (Coordinate crd in ft.Coordinates) {
coords.Append(new CE.Point(crd.X, crd.Y, (double.IsNaN(crd.Z) ? 0.0 : crd.Z)).ToXYZString());
coords.Append(" ");
}
if (coords.Length > 0)
retItems.Add(new List<string>() { "polyline", color, width, coords.ToString() });
}
else if (typ == FeatureType.Point) {
//coords
StringBuilder coords = new StringBuilder("");
foreach (Coordinate crd in ft.Coordinates) {
coords.Append(new CE.Point(crd.X, crd.Y, (double.IsNaN(crd.Z) ? 0.0 : crd.Z)).ToXYZString());
coords.Append(" ");
}
if (coords.Length > 0)
retItems.Add(new List<string>() { "point", color, width, coords.ToString() });
}
else if (typ == FeatureType.MultiPoint) {
//coords
StringBuilder coords = new StringBuilder("");
foreach (Coordinate crd in ft.Coordinates) {
retItems.Add(new List<string>() { "point", color, width, new CE.Point(crd.X, crd.Y, (double.IsNaN(crd.Z) ? 0.0 : crd.Z)).ToXYZString() });
}
}
else if (typ == FeatureType.Unspecified) {
}
}
index++;
done++;
}
EndProgress(StartingProgress);
}
catch { }
finally {
CloseProgress(StartingProgress);
}
return new List<object>() { retItems };
}
You can ignore the progress related items, but Norman Yuan did an excellent series on easy long process implementation at:
http://drive-cad-with-code.blogspot.ca/2015/04/showing-progress-for-long-code.htmlThe mapguide engine I mentioned is what autodesk uses in Map3D. Its crazy, but they actually give it away and you can use in any .net program you want.
We use it in Bricscad and basic acad for many things like making and importing kmz's.
I can't post my whole program. Our company does not sell any software yet.