Export all components of given type from manifold map file

You may sometime need to export all the components of given type so they can be used in another GIS environment. Here goes a script that does exactly this. The example exports all the drawings and tables to either shp or xls:

using Manifold.Interop.Scripts;
using M = Manifold.Interop;

class Script {
	static void Main() {
		//Some setup stuff first
        string exportFld = "H:\\ExportedComponents\\";

        M.Application mApp = Context.Application;
        M.Document mDoc = (M.Document)mApp.ActiveDocument;
        M.ComponentSet mCompSet = mDoc.ComponentSet;

        //Exporters
        M.ExportShp shpExporter = (M.ExportShp)mApp.NewExport("SHP");
        shpExporter.ConvertPolicy = M.ConvertPolicy.ConvertAll;

        M.ExportXls xlsExporter = (M.ExportXls)mApp.NewExport("XLS");
        xlsExporter.ConvertPolicy = M.ConvertPolicy.ConvertAll;

       //iterate through all components
        for (int i = 0; i < mCompSet.Count; i++ )
        {
            mApp.StatusText = "Reading component " + i.ToString() + " of " + mCompSet.Count;

            switch (mCompSet[i].Type)
            {
                case M.ComponentType.ComponentDrawing:

                    shpExporter.Export(mCompSet[i], exportFld + mCompSet[i].Name + shpExporter.DefaultExtension, M.ConvertPrompt.PromptNone);

                    break;

                case M.ComponentType.ComponentTable:

                    xlsExporter.Export(mCompSet[i], exportFld + mCompSet[i].Name + xlsExporter.DefaultExtension, M.ConvertPrompt.PromptNone);
                    break;
            }
        }

        mApp.StatusText = "";
        mApp.MessageBox("Done!", "Info");
	}
}

Creating a cost surface in Manifold

Recently I have played a bit with manifold to find out how to prepare a cost surface. There are no out of the box tools in manifold to magically create such a surface but a bit of sql does the job.

Lets assume we have two components - a surface and a drawing. Surface will be a container for our output data and the drawing will provide the input - in this case a bunch of simple lines imitating a road or stream network.

Lets start with preparing an output surface - simply copy the drawing and paste it as a surface and when done run an update query to set the cell values to 0:

UPDATE [Surface] SET [Height (I)] = 0

When our surface is ready we can start playing with generating a cost surface (in this case this will be a distance from the nearest vector object):

UPDATE
(SELECT
	[Surface].[Height (I)],
	Distance(
		AssignCoordsys(
			NewPoint([Center X (I)],[Center Y (I)]),
			CoordSys("Surface" AS COMPONENT)
		),
		Line.[Geom]
	) AS [Distance]
FROM
	[Surface],
	(SELECT AllBranches([Drawing].[Geom (I)]) As [Geom]
	FROM [Drawing]) AS Line)
SET [Height (I)] = [Distance];

 After running this query our surface should look like this:

So far s good but let's have a look at raster reclassification to make the output a bit more useful for further usage. We can write another query that will update our already generated surface, though for this example I have decided to combine it with the query above:

UPDATE
(SELECT
	[Surface].[Height (I)],
	Distance(
		AssignCoordsys(
			NewPoint([Center X (I)],[Center Y (I)]),
			CoordSys("Surface" AS COMPONENT)
		),
		Line.[Geom]
	) AS [Distance]
FROM
	[Surface],
	(SELECT AllBranches([Drawing].[Geom (I)]) As [Geom]
	FROM [Drawing]) AS Line)
SET [Height (I)] = 
	CASE
		WHEN  [Distance] < 5 THEN 0
		WHEN  [Distance] < 10 THEN 1
		WHEN  [Distance] < 15 THEN 2
		WHEN  [Distance] < 20 THEN 3
		WHEN  [Distance] < 25 THEN 4
		WHEN  [Distance] < 30 THEN 5
		WHEN  [Distance] < 35 THEN 6
		WHEN  [Distance] < 40 THEN 7
		WHEN  [Distance] < 45 THEN 8
		ELSE 9
	END

 So now our surface looks like this:

What's next? Having prepared more surfaces for analysis one can now combine them using surface tools. If surface tools are not avaialble it is easy enough to combine surfaces using the UPDATE technique shown above.

If you want to play a bit with the examples shown here just download this file: example.map (1.00 mb)

GeoServer production environment on Windows Server with IIS and Apache

In this post Andre explained how to set up a dev environment on win7 so Geoserver can coexist with IIS 7.5.

When it comes to deploying Geoserver to a machine that is exposed to the Internet things may go a bit more difficult. It actually took me a while to figure out how to make all the pieces work together so if you are in a similar situation - trying to run Geoserver on Windows Server - keep on reading.

We have decided to create a subdomain that will take all the traffic targeted at our Geoserver. Apart from looking unusual it certainly makes life easier when setting up rewrite rules for IIS. But let me explain it step by step.

 

1. Installing Apache Tomcat

I had some problems with Tomcat 7.0.6 and Geoserver 2.1RC1 (betas failed too) but luckily Tomcat 6.0.3 was ok. When installing the server it is worth to choose the service startup option so the Tomcat service starts automatically with WIndows. If you are running win x64 make sure you choose x64 JRE as well.

 

2. Making Tomcat pick a proper host name

By default Tomcat binds itself to the port 8080 an I have let it do so in this case as well. The problem though is that geoserver will pick the localhost:8080 for the capabilities documents and also for the example pages generated by the layer preview links. This is not a problem when working with geoserver locally but when accesssing it from another machine, the urls have to be resolved properly.

To make Tomcat know how of the host its pages are requested from I had to edit the tomcat/conf/server.xml file. By default the Connector tag does not have the proxyPort and proxyName properties so I needed to add them. proxyPort is the actual port the resource is requested through (the default is 80 and IIS listens at this port of course) and proxyName specifies the host name that will be used. Adding these two properties to the Connector section makes the geoserver report proxyName:proxyPort as the host name instead of localhost:8080 (in my case geoserver now uses http://geoserver.cartoninjas.net:80).

 

3. Deploying Geoserver

Since I have fixed the server.xml file I can start the Tomcat service and navigate to localhost:8080. After logging in I deployed Geoserver by using the war file available at the download page:

 

4. Setting a rewrite rule in IIS

Having installed Geoserver I was ready to route all the trafic to geoserver.cartoninjas.net to my Tomcat. I had the subdomain already created so there had to be a rewrite rule set appropriately. In my case I needed to have all the incoming traffic routed to localhost:8080:

 

5. Testing the geoserver from a remote computer

The final step was to test if everything worked ok. I have navigated to geoserver.cartoninjas.net/geoserver and tested the tiger ny layer group. It looked like everything was ok now ;-)

 

Why bothering with all the steps above? Initially I had the rewriting set in IIS and I could connect to geoserver through my subdomain. The actual problem though was with the capabilities documents but also with some of the automatically generated preview pages. Of course when knowing the actual resource location it was already possible to connect to the services exposed by geoserver. But clients trying to connect to the geoserver services automatically without knowing there was a problem with the host resolution would obviously fail. A dirty solution was to make the client application replace localhost:8080 with the actual host name and we had it working for quite a while. Luckily there was a bit more elegant way of fixng things and now we have our geoserver instance work as expected. I found that little proxy thing here.

Defitions of Polish projections for manifold

With version 8.0.19 manifold team added some of the Polish projections to manifold projection presets. Basically they added five zones of the National Coordinate System 1965 (PUWG 1965, zones I, II, III, IV and V). There seems to be a mistake though with the way they named the projections: National Coordinate System 1965 was named 1942 while the only one that has 5 zones for Poland is 1965.

For those interested in using Polish coordinate systems with manifold attached is a custom projection xml (it will display in a folder Poland_Custom in the assign / change projection dialog). This is the best we came up with so far so please bear in mind that it may not be 100% perfect. For some more details please see a discussion at georeference.org.

Styling Navteq data using Manifold

Recently we were asked to prepare some map layers for a web application. The exercise was about styling Navteq 2010 data in manifold so created maps can be then used for rendering a tiled base map but also used by a map server.

Although manifold lacks some of the carto tools available in other GIS packages or graphic software it does offer enough to complete such task. It actually does offer some other functions that let one create some nice map features - for example the road shields labels were created from a drawing linked to a SQL query that created road label points spaced evenly along the road lines. This backed with the automatic resolution of label conflicts allowed us to nicely place the road shields on the map.