MapIt GIS – Spatial Asset Collection, GPS Surveys and Spatial Data Management for Android

Please check out my new app for Android.

More details: http://mapit-gis.com
Get the app from Google Play

– Mobile app for asset collection, data management and environmental surveys.
– Survey layers (point, line, polygon).
– Attributes management.
– Google Maps, Bing Maps, Open Street Map base maps.
– Support for offline maps & Mapbox maps.
– Export, Import, Share (CSV, KML, geojson, arcjson).
– Measurement of the area, perimeter and distance.
– Support for multiple measurement units.
– Support for number of local coordinate systems.

pic1

 

Typical usage: environmental surveys, soil surveys, trees surveys, soil types mapping, mapping ecosystems, contractions, land measurement, real estate mapping, snow removal and many other to discover…

Related article: https://osedok.wordpress.com/2015/02/18/mapit-gis-data-collector

Generating mbtiles from an image

In number of emails I have been asked how to create an offline map from geo-referenced image. Please follow this article to create .mbtiles file ready to use with MapIt from an image. We use open source software to achieve the goal.

You need to have:

Please follow the steps below to get the offline map of Kilimanjaro in format compatible with MapIt:

1. Open qGIS and open a Georeferencer plugin as shown below:

qGIS Georeferencer plugin
qGIS Georeferencer plugin

2. Add your image to the plugin and set the spatial reference – you can use filter typing 4326 in the filter box.

Choose WGS84  spatial reference for your image
Choose WGS84 spatial reference for your image

3. Selecting georeferencing points.

Depending from the type of image you may use 4 or more points to georeference an image.
Zoom to the upper right corner and add point then enter longitude and latitude of that location:

Add lat, lon for the image corner.
Add lat, lon for the image corner.

Add another 3 points. Please make sure, that your working diagonally. In our example it would be: upper left, lower right, upper right, lower left. This will minimize problems according to the visibility of the map during georeferencing it.

Georeferencing points added to the image.
Georeferencing points added to the image.

4. Transformation settings

Before we georeference the image please go to Settings and set Transformation settings as shown on the picture below:

Georeference an image - transformation settings
Georeference an image – transformation settings

5. Georeference the image and add it to qGIS map view to check out if everything is fine.  Go to the used crossings of longitudes and latitudes and compare the shown coordinates with the desired coordinates. If they fit, you are done and ready for next step.

6. Before we use the image in Maperitive we need to convert the wld file (created during the georeference process above in the same location as the image) to georef file used by Maperitive.

Make sure that the number of decimal digits for the cell size is not>17 in georef file, otherwise Maperitive will complain.

Conversion of world file (wld) to georef file
Conversion of world file (wld) to georef file

World file content:

0.00012082694840728
0
0
-0.00012226615739132
37.11882655590969193
-2.90009944643156192

georef file content:

<georef>
<srs>
<id>EPSG:4326</id>
</srs>
<origin>
<x>37.11882655590969193
</x>
<y>-2.90009944643156192
</y>
</origin>
<cell-width>0.00012082694840728
</cell-width>
<cell-height>-0.000122266157391
</cell-height>
</georef>

8. Open Maperitive and type command:

clear-map

then

load-image file=Data\kilimanjaro.png background=false 

Maperitive load-image
Maperitive load-image
Georeferenced file loaded to Maperitive
Georeferenced file loaded to Maperitive

9. Generate .mbtiles file – please type the command below changing the zoom levels if necessary:

generate-mbtiles minzoom=0 maxzoom=15

Generate mbtiles
Generate mbtiles

10. rename the generated file to whatever name you want:

rename

11. Copy the file to the device memory card to MapIt->OfflineMaps folder:

phone offlinemaps

12. If you have MapIt offline maps extension your map will be available and ready to use – enjoy…

Offline Map within MapIt app.
Offline Map within MapIt app.

MapIt – GIS data collector

Last 6 months I have been working on new app. MapIt is now officially out, and available on Google Play, check it out. I am looking for feedback.

MapIt is a survey application. It’s excellent survey tool for any kind of GPS surveys and map based surveys. Spatial data collection (supported points, lines and polygons), asset management and asset surveys can be done faster and in more efficient way.
MapIt can be also used as a quick measurement tool to calculate area or distance.
When registering location simply choose required attributes from defined earlier drop-down list, no need to type the same information over and over again. Import long attributes list from text files if necessary and use them in number of projects. If necessary you can add one or more pictures to each location as well.

If you are you working in the field, gathering large amount of spatial/location based data this app is for you.
Map It is a very useful tool for anyone involved in forestry, agriculture, environmental or farming business and allows quick collection of spatial data without the need of typing similar information number of times.
Speed up your workflow and make the data collection more efficient. Take advantage of survey layers and possibility to reuse same set of attributes for multiple surveys. Export your data to common files like CSV, KML, GeoJSON, ArcGIS JSON and process them further using Desktop GIS software like ArcGIS, ArcGIS Online or open source QGIS and other professional tools like MS Office.

Please visit our website and follow a Walk-Through (sample tree’s survey) to understand better the application workflow.

Support for several global and local coordinate systems: WGS84 (decimal or degrees), Web Mercator, British National Grid, UTM SAD69 (Brazil), UTM NAD83, NATO, Stereo 70 (Romania), System 1992 (Poland), UTM Indian 1975 (Thailand), SIRGAS 2000 UTM coordinate system for South & Latin America, ETRS89 TM06 – Portugal, D73 Modified Portuguese Grid – if you require support for any other spatial reference please get in touch.
Selected features:
– Base maps: Google Maps, Bing Maps, Open Street Map, Mapbox and Offline mbtiles,
– Support for WMS and ArcGIS Server Tiled map services as Google Maps Overlays (Topographic maps, orthophoto maps, geological surveys, cadastral information and number of other country specific free services can be used now together with Google maps as an overlay),
– Possibility to create and maintain sets of attributes – these are available as a drop down lists when new feature is being recorded, long lists of values can be imported from text files.
– Clusters for map markers, efficient way of having large number of points on the map without performance issues,
– Currently 2 methods of collection are supported (GPS location, Map cursor location),
– Possibility to group your data into the survey layers – each survey layer may have a default set of attributes.
– Local SD card export or share option. At the moment KML, CSV, GeoJSON, ArcGIS JSON export is supported,
– Possibility to record multiple points, polylines and polygons on one layer,
– When creating new polygon or line features measurement details like area or length are also available.
– GPS and satellites status,
– Address, location search,
– Import point, line or polygon features into layer from CSV, KML or geojson files.
– Import attributes’ values from file
Our users are successfully using MapIt in number of applications including:
– environmental surveys,
– woodland surveys,
– forestry planning and woodland management surveys,
– agriculture and soils’ types surveys,
– road constructions,
– land surveying,
– solar panels applications,
– roofing and fencing,
– tree surveys,
– GPS surveying,
– site surveying and soil samples gathering

Build a RESTful API architecture within an ASP.NET MVC 3 application

Another one great article – it was exactly what I was looking for 🙂 . I have to highly reccommend it for reading.

http://iwantmymvc.com/rest-service-mvc3

Consuming WCF REST Services Using jQuery AJAX Calls

Very nice explained with lots of links and some useful functions like JSON object to html table:

http://www.codeproject.com/Articles/128478/Consuming-WCF-REST-Services-Using-jQuery-AJAX-Call

WCF 4.0 – Windows Authentication

I use the Windows Authentication very often in my everyday projects, so decided to write this article as it might be useful for you as well…

My aim was to create one web service with 2 endpoints having different HTTP methods available:

To achieve that you can use the WCF template available in VS 2010 as a start point:

1. Create new VS 2010 project using the Online Template (make sure .Net 4 is selected)

2. Modify the Service1.cs file replacing the original content with the code below:

Make sure that you have replace the WCF_Service_40 namespace with your original namespace.
As you can see we have added another contract class with methods available when user is authenticated.


using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;

namespace WCF_Service_40
{
// Start the service and browse to http://:/Service1/help to view the service's generated help page
// NOTE: By default, a new instance of the service is created for each call; change the InstanceContextMode to Single if you want
// a single instance of the service to process all calls.
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
// NOTE: If the service is renamed, remember to update the global.asax.cs file
public class Public_Service
{
// TODO: Implement the collection resource that will contain the SampleItem instances

[WebGet(UriTemplate = "")]
public List GetCollection()
{
// TODO: Replace the current implementation to return a collection of SampleItem instances
return new List() { new SampleItem() { Id = 1, StringValue = "Hello" } };
}

}

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Admin_Service
{
// TODO: Implement the collection resource that will contain the SampleItem instances

[WebGet(UriTemplate = "")]
public List GetCollection()
{
// TODO: Replace the current implementation to return a collection of SampleItem instances
return new List() { new SampleItem() { Id = 1, StringValue = "THis message can be seen only by authentificated users." } };
}

[WebInvoke(UriTemplate = "", Method = "POST")]
public SampleItem Create(SampleItem instance)
{
// TODO: Add the new instance of SampleItem to the collection
throw new NotImplementedException();
}

[WebGet(UriTemplate = "{id}")]
public SampleItem Get(string id)
{
// TODO: Return the instance of SampleItem with the given id
throw new NotImplementedException();
}

[WebInvoke(UriTemplate = "{id}", Method = "PUT")]
public SampleItem Update(string id, SampleItem instance)
{
// TODO: Update the given instance of SampleItem in the collection
throw new NotImplementedException();
}

[WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
public void Delete(string id)
{
// TODO: Remove the instance of SampleItem with the given id from the collection
throw new NotImplementedException();
}

}
}

3. Open Global.asax.cs file and replace it content to:

In the code below we are creating custom WebServiceHostFactoryclass. When registering route we can now add parameter ‘true’ or ‘false’ depending if we want the security to be turned on or off.


private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("soapService", new SoapServiceHostFactory(), typeof(Public_Service)));
RouteTable.Routes.Add(new ServiceRoute("restService", new CustomWebServiceHostFactory(false), typeof(Public_Service)));
RouteTable.Routes.Add(new ServiceRoute("adminService", new CustomWebServiceHostFactory(true), typeof(Admin_Service)));
}

Full code:


using System;
using System.ServiceModel.Activation;
using System.Web;
using System.Web.Routing;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Web.Configuration;
using System.Configuration;

namespace WCF_Service_40
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}

private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("soapService", new SoapServiceHostFactory(), typeof(Public_Service)));
RouteTable.Routes.Add(new ServiceRoute("restService", new CustomWebServiceHostFactory(false), typeof(Public_Service)));
RouteTable.Routes.Add(new ServiceRoute("adminService", new CustomWebServiceHostFactory(true), typeof(Admin_Service)));

}
}

public class SoapServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
host.AddServiceEndpoint(serviceType, new BasicHttpBinding(), "soap");
return host;

}

}

public class CustomWebServiceHostFactory : WebServiceHostFactory
{

private bool security_enabled;
public CustomWebServiceHostFactory(bool security_enabled)
{
this.security_enabled = security_enabled;
}

protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
WebServiceHost host = (WebServiceHost)base.CreateServiceHost(serviceType, baseAddresses);

if (security_enabled == false)
{
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });

ServiceEndpoint xml_endpoint = host.AddServiceEndpoint(serviceType, new WebHttpBinding { }, "XML");
xml_endpoint.Behaviors.Add(new WebHttpBehavior { DefaultBodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.Bare, HelpEnabled = true, DefaultOutgoingResponseFormat = WebMessageFormat.Xml });

ServiceEndpoint json_endpoint = host.AddServiceEndpoint(serviceType, new WebHttpBinding { }, "JSON");
json_endpoint.Behaviors.Add(new WebHttpBehavior { DefaultBodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.Bare, HelpEnabled = true, DefaultOutgoingResponseFormat = WebMessageFormat.Json });

}
else
{
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });

ServiceCredentials serviceCredential = host.Description.Behaviors.Find();
if (serviceCredential == null)
{
serviceCredential = new ServiceCredentials();
serviceCredential.WindowsAuthentication.AllowAnonymousLogons = false;
serviceCredential.WindowsAuthentication.IncludeWindowsGroups = true;
host.Description.Behaviors.Add(serviceCredential);
}

ServiceEndpoint xml_endpoint = host.AddServiceEndpoint(serviceType, new WebHttpBinding { Security = new WebHttpSecurity { Mode = WebHttpSecurityMode.TransportCredentialOnly, Transport = new HttpTransportSecurity { ClientCredentialType = HttpClientCredentialType.Windows, ProxyCredentialType = HttpProxyCredentialType.Windows } } }, "XML");
xml_endpoint.Behaviors.Add(new WebHttpBehavior { DefaultBodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.Bare, HelpEnabled = true, DefaultOutgoingResponseFormat = WebMessageFormat.Xml });

ServiceEndpoint json_endpoint = host.AddServiceEndpoint(serviceType, new WebHttpBinding { Security = new WebHttpSecurity { Mode = WebHttpSecurityMode.TransportCredentialOnly, Transport = new HttpTransportSecurity { ClientCredentialType = HttpClientCredentialType.Windows, ProxyCredentialType = HttpProxyCredentialType.Windows } } }, "JSON");
json_endpoint.Behaviors.Add(new WebHttpBehavior { DefaultBodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.Bare, HelpEnabled = true, DefaultOutgoingResponseFormat = WebMessageFormat.Json });

}
return host;

}

}

}

4. Try to access the adminService using debugging:

You should be getting the error from the picture below:

4. To add the windows authentication publish your WCF Service on IIS 7 (Windows Vista, 7 Home edition do not support the Windows authentification – you have to have the proffesional version of the operating system to enable it).

5. Add Blank ‘AdminService’ folder to your deployment folder and enable the windows authentication on it as shown on the picture below:

6. If you still cannot get the AdminServis URI working try to edit the C:\Windows\System32\inetsrv\config\applicationHost.config file changing overrideModeDefault value for Anonymus and Windows authentication type as shown below.

 

7. When it’s configured properly you should be able to access both endpoint using different authentification method.