Com And Hosting

Recently I was working on a project to build an interactive map using geoJson, LeafletJs, Handlebar, Bootstrap in ASP.NET MVC framework. I have tried to use the geoJson.net package for the ASP.NET MVC framework. The package seems to be very promising however I was facing some issues could not overcome. It returns valid geoJson data but it does not include the “Point” in the Geometry datatype instead it returns 0. I couldn’t access this property to override and spent hours to fiddle around with no luck. I have then faced another problem the json output does not include the “Feature” as type in the Featurecollection instead it returns 7. This was another weird issue that I couldn’t override the default property value for this item.

Here is the output I was getting using the geoJson.net package –

geoJSON data

 

You can see the highlighted fields with the wrong data. I have used the following code to generate the above geoJSON data.

public ActionResult GeoJson()
        {

            var contactResponse = _db.Contacts.OrderByDescending(c => c.LastUpdated).Select(contact => new
            {
                contact.ID,
                contact.ContactName,
                contact.AddressSuburbTown,
                contact.Telephone,
                contact.TelephoneSecondary,
                contact.LastUpdated,
                contact.LocationLat,
                contact.LocationLng,
                contact.ServiceAvailableDetailed
            }).ToList();

            var collection = new FeatureCollection() { /* CRS = new NamedCRS("EPSG:31370") */ };
            var pointList = new List<Feature>();
            foreach (var results in contactResponse)
            {
               
                var position = new Position(float.Parse(results.LocationLng), float.Parse(results.LocationLat), altitude: 0);

                var point = new Point(position) { /*CRS = new NamedCRS("EPSG:31370")*/ };


                var geom = new Point(

                    new Position(float.Parse(results.LocationLng), float.Parse(results.LocationLat), altitude: 0)
                );
                var json = JsonConvert.SerializeObject(point, Formatting.Indented);
                Point actualPoint = JsonConvert.DeserializeObject<Point>(json);

                var id = results.ID.ToString();


                var properties = new Dictionary<string, object>
                    {
                        {"type", "Something else" },
                        {"id", results.ID},
                        {"Name", results.ContactName},
                        {"Services", results.ServiceAvailableDetailed },
                        {"telephone", results.Telephone},
                        {"address", results.AddressSuburbTown},
                        {"another field", "this is another field" }


                    };

               
                var feature = new Feature(point, properties, id);

                pointList.Add(feature);
                //add the feature to the feature collection
                collection.Features.Add(feature);
            }

         
            return Json(pointList, JsonRequestBehavior.AllowGet);
        }

As you can see from the above code, it gets the data from the database table then loop through the dataset and add the properties and points to the Featurecollection array. It looks very straightforward but for whatever reason, it does not include the “Point” in the Geometry type field. Interesting when I debug and inspect the point field, it shows the string correctly e.g. {“type”: “Point”, coordinates: [ 43.543534, 114.45434]}.

After spending many hours by fiddling with this package. I have made my mind to write my own custom code to generate geoJSON data through the api. Here is what I have done and it works perfectly.

public ActionResult geoJson()
        {


            var contactResponse = _db.Contacts.OrderByDescending(c => c.LastUpdated).Select(contact => new
            {
                contact.ID,
                contact.ContactName,
                contact.AddressSuburbTown,
                contact.Telephone,
                contact.TelephoneSecondary,
                contact.LastUpdated,
                contact.LocationLat,
                contact.LocationLng,
                contact.ServiceAvailableDetailed
            }).ToList();

            List<dynamic> myCollection = new List<dynamic>();

            
            foreach (var con in contactResponse)
            { 

                //check the null address
                
                var adr = con.AddressSuburbTown ?? "NA";

                var str = new
                {
                    type = "Feature",
                    id = con.ID,
                    geometry = new {
                        type = "Point", coordinates = new[] { float.Parse(con.LocationLng), float.Parse(con.LocationLat) }


                    },
                    properties = new
                    {
                        type = "Feature",
                        id = con.ID,
                        name = con.ContactName,
                        services = con.ServiceAvailableDetailed,
                        telephone = con.Telephone,
                        address = adr
                   }
               
                };
                
                    myCollection.Add(str);

            }
            
            return Json(myCollection.ToArray(), JsonRequestBehavior.AllowGet);
        }

The above code generates the valid geoJSON data that works perfectly with the leafletJs. Here is the output data after writing this program. Very simple codes and serve the requirement for my project.

 

 

 

 

I can now use the geoJSON data in the leafletJs to render the interactive map. Below is the example of the rendered map.

 

 

Here is the javascript to get the geoJson data and renders the layer on the map.

var contactLayer = L.geoJson(null);

var contacts = L.geoJson(null, {
    pointToLayer: function (feature, latlng) {
        return L.marker(latlng, {
            icon: L.icon({
                iconUrl: "/contactsearch/img/theater.png",
                iconSize: [24, 28],
                iconAnchor: [12, 28],
                popupAnchor: [0, -25]
            }),
            title: feature.properties.name,
            riseOnHover: true
        });
    },
    onEachFeature: function (feature, layer) {
       
       // alert(feature.properties.name);
        if (feature.properties) {
            
            var content = "<table class='table table-striped table-bordered table-condensed'>" + "<tr><th>Name</th><td>" + feature.properties.name + "</td></tr>" + "<tr><th>Phone</th><td>" + feature.properties.telephone + "</td></tr>" + "<tr><th>Address</th><td>" + feature.properties.address + "</td></tr>" + "<tr><th>Website</th><td><a class='url-break' href='" + feature.WebsiteURL + "' target='_blank'>" + feature.WebsiteURL + "</a></td></tr>" + "<table>";
            layer.on({
                click: function (e) {
                    $("#feature-title").html(feature.properties.name);
                    $("#feature-info").html(content);
                    $("#featureModal").modal("show");
                    highlight.clearLayers().addLayer(L.circleMarker([feature.geometry.coordinates[0], feature.geometry.coordinates[1]], highlightStyle));
                }
            });
            $("#feature-list tbody").append('<tr class="feature-row" id="' + L.stamp(layer) + '" lat="' + layer.getLatLng().lat + '" lng="' + layer.getLatLng().lng + '"><td style="vertical-align: middle;"><img width="16" height="18" src="/contactsearch/img/theater.png"></td><td class="feature-name">' + 'fdsfsd fsdfdsfsd' + '</td><td style="vertical-align: middle;"><i class="fa fa-chevron-right pull-right"></i></td></tr>');
            contactSearch.push({
                name: layer.feature.properties.name,
                address: layer.feature.properties.address,
                source: "Contacts",
                id: L.stamp(layer),
                lat: layer.feature.geometry.coordinates[1],
                lng: layer.feature.geometry.coordinates[0]
            });
        }
    }
});
$.getJSON(baseUrl + "/data/contacts.json", function (data) {
    contacts.addData(data);
    console.log(data);

    
    map.addLayer(contactLayer);
});

 

4 thought on “Creating geoJson in ASP.NET MVC 5 API for Leaflet map”
  1. Wow. great job.. could you email me the full code? i tried so hard but nothing, and i need to use mysql.

Leave a Reply

Your email address will not be published. Required fields are marked *