📜 ⬆️ ⬇️

Using MapXtreme .Net

Hello! I want to share with you my experience with the SDK such as MapXtreme .Net from Pitney Bowes. As stated on their website:
MapInfo MapXtreme for .Net is a GIS software development kit in the Microsoft .Net environment that allows you to embed cartographic and GIS functions in business applications.

Installation


The first step was setting the machine to work. We install MS VisualStudio 2015 from the developer's site (it works on MSVS2010, did not try to be lower than the version).

Download the installation package from the developer's site. A trial version 7.1 is available for download on the portal for 60 days (version 8 is available for purchase, the difference between them is palpable, but affects the architecture of MapXtreme. Basic operations remained unchanged).

It is also necessary to download a map of the world, otherwise why do we need a GIS at all, right? For MapXtreme, the ADC WorldMap Version 7.1 is suitable.
')
Put in exactly this order, as MapXtreme requires .Net.

Documentation


The library is very large with lots of features, but to get to them you need documentation, and MapXtreme has problems with it. After installation in the directory with the SDK you can find
MapXtreme Developers Reference
MapXtreme Version 8.0 Developer Guide

The materials themselves contain examples at the level of the captain obvious, or are absent altogether. On the Internet, this library also does not contain many explanatory resources. The best was on the site of the developer . However, about six months ago, they closed access to it and began to send everyone to tech support.

By the way, a few words about her darling:

image

There were 3-4 appeals to them for help, and all times they told me:
“We passed your request to our developers”
“Send your source code to us, we do not understand your problem”, etc.

For the card there is also a guide, which is useful. It describes all the tags and values ​​that can be set.

Development


If you installed everything correctly, VisualStudio when creating a new project you will have the MapXtreme project type (I have version 8.0, because we bought a license).

image

Choose a Windows Form App. If no new items appear in the ToolBox, open the menu item
Tools → Choose ToolBox Items ...

And in the window that appears, choose the tools we need:

image

So, we all installed, configured and ready to write code MapXtreme provides ready-made components for creating an application. You can immediately make the MapXteme toolbar by adding a ToolStrip component to the main form, which stores the buttons we need.

image

To use the buttons that we selected for the MapControl property, we write the name of our element of the type MapControl. My name is mapControl1, yours may be different. Or in the form designer to write

private void Form1_Load(object sender, EventArgs e) { addrectangleToolStripButton1.MapControl = mapControl1; .... } 

If everything is done correctly, then you should get this:

image

“I did everything right, I chose a drawing tool, but nothing works out for me! Why?"

To solve this problem, you must select the layer on which we will draw and make it changeable. By default, all layers on mapControl are immutable.

We can solve our problem with MapXtreme by clicking the “Layer Control” button and ticking the right places.

image

Or do it right in the code:

 var layerTemp = mapControl1.Map.Layers["wldcty25"]; LayerHelper.SetInsertable(layerTemp, true);//      LayerHelper.SetEditable(layerTemp, true); //    

I note that you can only draw on the "upper" layer, that is, in order to draw an object, we need to move our "wldcty25" layer up:

image

Or write in the code:

 mapControl1.Map.Layers.Move(lastPosition, nextPosition); 

As a result, our first object is drawn:

image

As I said earlier, any setting can be specified via the interface. However, the customer is often fastidious and he needs more flexible / accessible configuration elements, so I’ll not talk about how to configure something through MapXtreme components. I will show how to do this through code.

I want to start with the style. The main class responsible for the design is CompositeStyle . In MapXtreme, we can style the layer and the object. I note that the layer style overlaps the style of the object.

 SimpleLineStyle border;//   border= new SimpleLineStyle(<    MapXtreme>, <  >, < >) SimpleInterior interior;//    interior = new SimpleInterior(< >, <  >,< >) AreaStyle polygon;//          polygon = new AreaStyle(border, interior); SimpleLineStyle line;//   line = new SimpleLineStyle(<    MapXtreme>, <  >, < >) BasePointStyle point;//   point = new SimpleVectorPointStyle(< >, < >, < >) CompositeStyle compStyle;//    compStyle = CompositeStyle(polygon, line, null, point); 

Apply this style to the layer:

 FeatureOverrideStyleModifier fosm; fosm = new FeatureOverrideStyleModifier(parStyleName, parStyleAlias, compStyle); myLayer.Modifiers.Append(featureOverrideStyleModifier); 

Apply the received style to the object:

 Feature feature = null; feature = new Feature(<   >, compStyle); 

Object creation


To create a multiline or multipolygon, we first create the source data:

 //    DPoint[] pts1 = new DPoint[5]; pts1[0] = new DPoint(-20, 10);//      pts1[1] = new DPoint(10, 15); pts1[2] = new DPoint(15, -10); pts1[3] = new DPoint(-10, -10); pts1[4] = new DPoint(-20, 10); //    DPoint[] pts2 = new DPoint[5]; pts2[0] = new DPoint(-40, 50); pts2[1] = new DPoint(60, 45); pts2[2] = new DPoint(65, -40); pts2[3] = new DPoint(25, 20); pts2[4] = new DPoint(-40, 50); //LineString     DPoint LineString lineString1 = new LineString(coordSys, pts1); LineString lineString2 = new LineString(coordSys, pts2); 

Using the code above create:

- multipolygon

 //Ring     coordSys   LineString Ring ring1 = new Ring(coordSys, lineString1); Ring ring2 = new Ring(coordSys, lineString2); Ring[] rng1 = new Ring[2]; rng1[0] = ring2; rng1[1] = ring1; //MultiPolygon    Ring MultiPolygon multiPol = new MultiPolygon(coordSys, rng1); 

- multiline

 //Curve     coordSys   LineString Curve curve4 = new Curve(coordSys, lineString1); Curve curve5 = new Curve(coordSys, lineString2); Curve[] crv = new Curve[2]; crv[0] = curve5; crv[1] = curve4; //MultiCurve    Curve MultiCurve mc = new MultiCurve(coordSys, crv); 

Work with map projection


Receiving:

 CoordSys oordSys= mapControl1.Map.GetDisplayCoordSys(); 

Creating and changing the current coordinate system:

 CoordSys cs = Session.Current.CoordSysFactory.CreateCoordSys("EPSG:3395", CodeSpace.Epsg); mapControl1.Map.SetDisplayCoordSys(cs); 

In fact, there are a lot of overloaded constructors, but usually two are enough, since in practical tasks work in three or four coordinate systems is necessary.

I have not said anything about working with bitmaps. She is here as well. However, if you change the coordinate system, then your image is unlikely to be transformed if you do not register a trace. line:

 mapControl1.Map.RasterReprojectionMethod = ReprojectionMethod.Always; /** *ReprojectionMethod    * None = 0, //    * Always = 1,//  * Optimized = 2//     ,         *  */ 

Personally, I only worked with GeoTiff. MapXtreme does not work directly with images. In order for everything to be good, the system needs a * .tab file that will contain a description of the raster, the coordinate system, the coordinates of the corners.

How to do * .tab for a raster using MapXtreme means I didn’t find it, the Internet didn’t give any hints either, and I had to write the method myself that would create this file:

 private string CreateTabFile(List<DoublePoint> parImageCoordinate)//   { NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat; var ext = m_fileName.Split(new Char[] { '.' }); var fileExt = ext[ext.GetLength(0) - 1]; string fileTabName = m_fileName.Substring(0, m_fileName.Length - fileExt.Length) + "TAB"; StreamWriter sw = new StreamWriter(fileTabName); string header = "!table\n!version 300\n!charset WindowsCyrillic\n \n"; sw.WriteLine(header); string definitionTables = "Definition Table\n "; definitionTables += "File \"" + m_fileName + "\"\n "; definitionTables += "Type \"RASTER\"\n "; for (var i = 0; i < parImageCoordinate.Count; i++) { definitionTables += "(" + parImageCoordinate[i].Longitude.ToString("N", nfi) + "," + parImageCoordinate[i].Latitude.ToString("N", nfi) + ") "; definitionTables += "(" + parImageCoordinate[i].PixelColumn.ToString() + "," + parImageCoordinate[i].PixelRow.ToString() + ") "; definitionTables += "Label \" " + (i + 1).ToString() + " \",\n "; } definitionTables = definitionTables.Substring(0, definitionTables.Length - 4); definitionTables += "\n "; definitionTables += "CoordSys Earth Projection 1, 104\n "; definitionTables += "Units \"degree\"\n"; sw.WriteLine(definitionTables); string metaData = "begin_metadata\n"; metaData += "\"\\IsReadOnly\" = \"FALSE\"\n"; metaData += "\"\\MapInfo\" = \"\"\n"; string hash; using (MD5 md5Hash = MD5.Create()) { hash = GetMd5Hash(md5Hash, m_fileName); } metaData += "\"\\MapInfo\\TableID\" = \"" + hash + "\"\n"; metaData += "end_metadata\n"; sw.WriteLine(metaData); sw.Close(); return fileTabName; } 

The GetMd5Hash method is taken from MSDN . So now our mapControl1 is ready to work with a raster.

All for now. It turned out and volume, I guess. Why decided to write? Because I did not find any good content on this issue either in Habré or in the Internet segment of the Internet.

Source: https://habr.com/ru/post/331590/


All Articles