Tag Archives: Web Mapping

ESRI JavaScript API and DOJO – I Hate You.

8 Nov

I am by no means a JavaScript expert and herein may be my problem, but I will rant anyway – if I am wrong, feel free to explain why or just troll me (I will approve your comment).

I hate the ESRI JavaScript API and I have finally figured out why – I do not like Dojo. I may be the old man yelling “get off my lawn!” but I like simplicity. I am not the only one. So does Vladimir Agafonkin – check out his talk at FOSS4G “How Simplicity Will Save GIS.” Vladimir is the creator of Leaflet.js. I love Leaflet. It is simple, but it can do complicated things. There are several plugins listed on the Leaflet website and you can always write your own.

The ESRI JavaScript API does not feel simple (their Leaflet.js plugin is. That’s right. They have a plugin for Leaflet too, so why Dojo?). Maybe it is just my lack of knowledge in Dojo and I am going through the 7 Stages of Learning Dojo. I refuse to learn Dojo. Not because there is anything wrong with Dojo, but because I think ESRI chose it for all the wrong reasons.

I think ESRI always goes down the wrong road and for the wrong reasons. When ESRI decided to get a “modern” web platform, what did they do? They released Silverlight and Flex APIs. Maybe you like them, I do not. Just like Dojo, it is not the technology I have an issue with but rather my issue is with why I think ESRI chose them.

Why Did ESRI Choose Silverlight, Flex and Dojo?

They wanted it to look pretty and have a bunch of widgets already built.

Therein lies the reason for my hatred of all three of those ESRI APIs. They did it for looks – bells and whistles – first and foremost. You don’t have to build everyhting, just provide the framework for users to do so. Leaflet has a way to create user controls: var MyControl = L.Control.extend …

It always seems like ESRI is in a hurry to put something out. I am almost surprised they didn’t just use GeoEXT.js. I mean, you can move a frame around the screen!

I will continue to use ESRI applications on a daily basis. I will also use Leaflet and the ESRI Plugin – I actually use Leaflet Vector Layers plugin more. I will not use the JavaScript API and I will not learn Dojo (at least anytime soon).

I will end the post on a positive note – I have read that ArcObjects is dead and in ArcGIS Pro, the .NET coding is much simpler. I found ArcGIS Desktop Explorer to have an easier API than ArcMap so if it is anything like that, I will be a happy camper.

Here is to ESRI abandoning Python, JavaScript and .NET and making us all program in Go.

 

Advertisements

Convert MongoDB to GeoJSON: Use in Leaflet.js

16 Nov

Leaflet.js is my favorite tool for making quick web maps. Using GeoJSON, you can feed data to Leaflet either by pasting it in to your code or by making it a variable and saving it as a .JS and importing it. How you do it is up to you, but in this example I am going to copy and paste in my GeoJSON text. My GeoJSON will be generated from a mongoDB using Python.
I created a mongoDB with a series of points (Long, Lat). Then I wrote a Python script to grab all those points and dump them in to a GeoJSON file. Lastly, I paste that as a variable in my Leaflet code.
Taking this project further, try using the select near, or select near where type:coffee shop, features in mongoDB. You could use bounding boxes too.

Here is the python code to convert mongoDB to GeoJSON:

from pymongo import Connection,GEO2D
db=Connection().geo

geojson=open(“mongoLoop.json”,”w”)
geojson.write(‘{ “type”: “FeatureCollection”,’+”\n”)
geojson.write(‘”features”: [‘+”\n”)

x=0
d=db.places.count()

for i in db.places.find():
if x < d-1:
geojson.write(‘{ “type”: “Feature”,’+”\n”)
geojson.write(‘”properties”: {“popup”: “value0”},’)
geojson.write(‘ “geometry”: {“type”: “Point”, “coordinates”: [‘)
p1=i[“loc”][0]
p2=i[“loc”][1]
geojson.write(str(p1)+’,’+str(p2)+’]}},’+”\n”)
x=x+1
print “x =” + str(x)
else:
geojson.write(‘{ “type”: “Feature”,’+”\n”)
geojson.write(‘”properties”: {“popup”: “value0”},’)
geojson.write(‘ “geometry”: {“type”: “Point”, “coordinates”: [‘)
p1=i[“loc”][0]
p2=i[“loc”][1]
geojson.write(str(p1)+’,’+str(p2)+’]}}’+”\n”)
print “Last Loop”

geojson.write(‘]}’)
geojson.close()

And the output:

{ “type”: “FeatureCollection”,
“features”: [
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [35,-106]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [35.8,-106.8]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [38,-108]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [39,-109]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [30,-100]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [31,-101]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [31,-102]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [31,-103]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [33,-100]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [25,-102]}}
]}

Lastly the HTML to create the Leaflet map – input your API Key:

<!DOCTYPE html>
<html>
<head>
<title>My Map</title>
<meta charset=”utf-8″ />

<link rel=”stylesheet” href=”http://cdn.leafletjs.com/leaflet-0.4/leaflet.css&#8221; />
<!–[if lte IE 8]><link rel=”stylesheet” href=”http://cdn.leafletjs.com/leaflet-0.4/leaflet.css&#8221; /><![endif]–>
</head>
<body>
<div id=”map” style=”width: 600px; height: 400px”></div>

<script src=”http://cdn.leafletjs.com/leaflet-0.4/leaflet.js”></script&gt;

<script>

var map = L.map(‘map’).setView([35, -106], 13);

L.tileLayer(‘http://{s}.tile.cloudmade.com/API-KEY/997/256/{z}/{x}/{y}.png’, {
attribution: ‘Map data &copy; <a href=”http://openstreetmap.org”>OpenStreetMap</a&gt; contributors, <a href=”http://creativecommons.org/licenses/by-sa/2.0/”>CC-BY-SA</a&gt;, Imagery © <a href=”http://cloudmade.com”>CloudMade</a>&#8217;,
maxZoom: 18
}).addTo(map);

var mongo = { “type”: “FeatureCollection”,
“features”: [
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [-106, 35]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [-106.8,35]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [-108, 38]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [-109, 39]}},
{ “type”: “Feature”,
“properties”: {“popup”: “value0”}, “geometry”: {“type”: “Point”, “coordinates”: [30,-100]}}
]};

var myLayer = L.geoJson().addTo(map);
myLayer.addData(mongo);

</script>
</body>
</html>

OpenLayers and Revit

16 Jul

In a previous post, I showed how OpenLayers could display Autocad Files. OpenLayers, using an Image Layer, can also display an Ortho of your model. While I would prefer a 3D PDF, this may have its uses.

Here is the Revit model as a web map.

I took 3 shots of a Revit model and added two points. I used a blank white image as the background, a full model layer – which is active at the start, a layer with no walls, and a frame layer. By clicking down the layers, you can remove pieces of the building. I did not fix resolutions in my code, but the images can be more crisp. Here is a shot with the Frame Layer turned on.

To see the map live go to my website:
http://educationalfacilityplanning.com/3DOpenLayers.html

Leaflet.js Interactivity II: Allow Users to Add Points

29 Jun

In Part I, I showed how to use buttons to add and remove layers, and how to capture popup text and display it in a <DIV> element. In this post I will show how to allow users to create their own points with popups. Here is an image of the page with no input yet.

First, I created a blank map with just a Cloudemade Tile.

Second, I created a <DIV> to hold my form:

<div>
LAT:<input type=”text” id=”lat”>
LONG:<input type=”text” id=”long”>
POPUP:<input type=”text” id=”popuptext” value=”POPUPTEXT”>
<button onclick=”createPoint()”>Create Point</button>
</div>

Lastly, I create the function in the form:

function createPoint()
{
var lat = document.getElementById(‘lat’).value;
var long = document.getElementById(‘long’).value;
var pop = document.getElementById(‘popuptext’).value;
var latint = parseInt(lat);
var longint = parseInt(long);
var mora = new L.LatLng(latint, longint),
MSD = new L.Marker(mora);
map.addLayer(MSD);
MSD.bindPopup(pop);
}

To see it working go to EducationalFacilityPlanning.com/UserAddPoints.html

Try typing in 35, -106 for Lat and Long

This needs more work, like a function to allow the user to click on the map and get a long,lat pair:

map.on(‘click’, onMapClick);
var popup = new L.Popup();

function onMapClick(e) {
var latlngStr = ‘(‘ + e.latlng.lat.toFixed(3) + ‘, ‘ + e.latlng.lng.toFixed(3) + ‘)’;

popup.setLatLng(e.latlng);
popup.setContent(“You clicked the map at ” + latlngStr);

map.openPopup(popup);
}

But, more importantly, a function to save the points so the user can recreate their map.

 

Happy Hacking

 

Leaflet.js and GeoJSON

12 Apr

Recently, I have been playing with a few different open source GIS tools and Leaflet.js has been one I really like – OpenLayers is next on my To-Do list. In this post, I will show a very simple example of loading GeoJSON point data in to a map and then adding a popup to the points. I modified the example from the Leaflet website, stripping out other ways of doing it and simplified the GeoJSON to one data object. I think for newbies like myself, this made it much easier to understand.

Here is a screen shot of the final map – 2 points with a popup.

The Final Leaflet.js Map.

The following is the GeoJSON I used – it contains 2 points.

GeoJSON file saved as .js

Now in the webpage, I create a Leaflet map and use the GeoJSON file. Here is the code:

Here is what’s happening:

Import the GeoJSON data: <script src=”MyGeoJSONforLightRail.js” type=”text/javascript”></script>

Create a place to put the map: <div id=”map” style=”width: 600px; height: 400px”></div>

Add a map named same as place we want to put it: var map = new L.Map(‘map’);

Add a base map, set the map zoom, add the base layer to the map:

var cloudmadeUrl = ‘http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/22677/256/{z}/{x}/{y}.png’, cloudmadeAttribution = ‘Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade’,  cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution});

map.setView(new L.LatLng(39.747, -105), 14).addLayer(cloudmade);

Create and empty GeoJSON Layer: var lightRailGeojsonLayer = new L.GeoJSON();

Attach a popup: lightRailGeojsonLayer.on(“featureparse”, function (e) {
var popupContent = “<p>I started out as a GeoJSON ” + e.geometryType + “, but now I’m a Leaflet vector!</p>”;
popupContent += “<p>This is the default look of a GeoJSON Point.</p>”;
if (e.properties && e.properties.popupContent) {
popupContent += e.properties.popupContent;
}
e.layer.bindPopup(popupContent);
});

Note on Popup: The += following popupContent is appending to the string. You will see it 3 times.

Add the blank GeoJSON layer to the map: map.addLayer(lightRailGeojsonLayer);

Populate the layer with the .js file we included in the header (MyGeoJSONforLightRail.js):

lightRailGeojsonLayer.addGeoJSON(lightRailStop);

Note on populating: the (lightRailStop) is the name of the var in the MyGeoJSONLightRail.js file:

var lightRailStop = {
“type”: “FeatureCollection”,
“features”: [ blah blah blah…..

 

There you go. Change the GeoJSON to your file, modify the map setView, and edit the popup and you have your own map. For more examples go to the Leaflet page.