{"id":12,"date":"2018-05-08T09:03:11","date_gmt":"2018-05-08T13:03:11","guid":{"rendered":"http:\/\/www.dev-notes.com\/blog\/?p=12"},"modified":"2018-05-08T12:22:55","modified_gmt":"2018-05-08T16:22:55","slug":"implementing-openstreetmap","status":"publish","type":"post","link":"https:\/\/www.dev-notes.com\/blog\/2018\/05\/08\/implementing-openstreetmap\/","title":{"rendered":"Implementing OpenStreetMap"},"content":{"rendered":"<p>Google recently announced a change in their Maps API usage quota that will inevitably move some current users from the previously free tier into a paid tier.  I thought this might perhaps drive more developers to switch from Google Maps to OpenStreetMap if only for budget reasons, so hopefully the following guide would help get things started.<\/p>\n<p>OpenStreetMap implementation is actually just as simple as Google Maps, especially when coupled with Javascript libraries focused on building maps.  In the following example, I used <a href=\"https:\/\/leafletjs.com\" rel=\"nofollow\" target=\"_leafletjs\">Leaflet<\/a>.  As far as tiles are concerned, I used tiles by <a href=\"http:\/\/stamen.com\" rel=\"nofollow\" target=\"_stamen\">Stamen<\/a>.  While I personally like Stamen&#8217;s tiles a lot, there are many tiles available across the web with different styles, and some might fit your particular niche or style better; check out <a href=\"http:\/\/leaflet-extras.github.io\/leaflet-providers\/preview\/index.html\" rel=\"nofollow\" target=\"_leaflet-extras.github.io\">this link<\/a> for a few others.  Finally, for the data, I used some data from Lava&#8217;s <a href=\"http:\/\/ww2db.com\" target=\"_ww2db\">WW2DB<\/a> project.<\/p>\n<p>To get things started, I created a div that will eventually contain the map.  Then, I linked to the .css stylesheet and the .js package files:<\/p>\n<pre class=\"code\">\r\n&lt;div id=\"mapdiv\" style=\"width: 400px; height: 400px;\"&gt;&lt;\/div&gt;\r\n&lt;link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.3.1\/dist\/leaflet.css\" integrity=\"sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==\" crossorigin=\"\"\/&gt;\r\n&lt;script src=\"https:\/\/unpkg.com\/leaflet@1.3.1\/dist\/leaflet.js\" integrity=\"sha512-\/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==\" crossorigin=\"\"&gt;&lt;\/script&gt;\r\n<\/pre>\n<p>Then, a snippet of PHP code fetched necessary data from the WW2DB backend database, and used the data to build a Javascript array.  The resulting Javascript array that I built looked something like this:<\/p>\n<pre class=\"code\">\r\nvar rawDataArray = [\r\n\t{ \"name\": \"This is marker #1\", \"lat\": \"10\", \"lng\": \"10\" },\r\n\t{ \"name\": \"This is marker #2\", \"lat\": \"20\", \"lng\": \"20\" },\r\n\t{ \"name\": \"This is marker #3\", \"lat\": \"30\", \"lng\": \"30\" },\r\n\t...\r\n];\r\n<\/pre>\n<p>Now comes the main part.  You will see that it is not too complex, even if have little experience with Google Maps, OpenStreetMap, or Leaflet.<\/p>\n<pre class=\"code\">\r\n\/\/ Initialize the map (parameters: initial latitude, initial longitude, zoom level)\r\nvar mymap = L.map('mapdiv').setView([0, 0], 13);\r\n\r\n\/\/ Specify tiles\r\nL.tileLayer('https:\/\/stamen-tiles-{s}.a.ssl.fastly.net\/terrain\/{z}\/{x}\/{y}.{ext}', {\r\n\tattribution: 'Tiles &lt;a href=\"http:\/\/stamen.com\">Stamen Design&lt;\/a>, &lt;a href=\"http:\/\/creativecommons.org\/licenses\/by\/3.0\">CC BY 3.0&lt;\/a> &mdash; Data &lt;a href=\"http:\/\/www.openstreetmap.org\/copyright\">OpenStreetMap&lt;\/a>',\r\n\tsubdomains: 'abcd',\r\n\tminZoom: 0,\r\n\tmaxZoom: 18,\r\n\text: 'png'\r\n}).addTo(mymap);\r\n\r\n\/\/ Loops through the raw data, place a point on the map, and build an array of the points\r\nvar circleArray = [];\r\nfor (var i = 0; i < rawDataArray.length; i++) {\r\n\tvar rawData = rawDataArray[i];\r\n\tcircle = new L.circle([rawData[\"lat\"], rawData[\"lng\"]], {\r\n\t\tcolor: 'red',\r\n\t\tfillColor: '#f03',\r\n\t\tfillOpacity: 0.5,\r\n\t\tradius: 50\r\n\t}).addTo(mymap).bindPopup(L.popup({maxHeight:200}).setContent(rawData[\"name\"]));\r\n\tcircleArray.push(circle);\r\n}\r\n\r\n\/\/ Adjust the map view based on the array of points, so the map won't appear to be zoomed overly in or out\r\nvar group = new L.featureGroup(circleArray);\r\nmymap.fitBounds(group.getBounds());\r\n<\/pre>\n<p>Here's an example I implemented for showing WW2-era facilities found on the island of Taiwan:<\/p>\n<div id=\"mapdivTaiwan\" style=\"width: 400px; height: 400px;\"><\/div>\n<link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.3.1\/dist\/leaflet.css\" integrity=\"sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==\" crossorigin=\"\"\/>\n<script src=\"https:\/\/unpkg.com\/leaflet@1.3.1\/dist\/leaflet.js\" integrity=\"sha512-\/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==\" crossorigin=\"\"><\/script><br \/>\n<script>\nvar rawDataArray = [\n\t{ \"name\": \"Koshun Airfield\", \"lat\": \"22.036325000\", \"lng\": \"120.731674000\" },\n\t{ \"name\": \"Takao Seaplane Base\", \"lat\": \"22.567442000\", \"lng\": \"120.323695000\" },\n\t{ \"name\": \"Reigaryo Airfield\", \"lat\": \"22.607348000\", \"lng\": \"120.297570600\" },\n\t{ \"name\": \"Hozan Airfield\", \"lat\": \"22.635243000\", \"lng\": \"120.406122000\" },\n\t{ \"name\": \"Heito Airfield\", \"lat\": \"22.674173000\", \"lng\": \"120.461215000\" },\n\t{ \"name\": \"Takao Guard District\", \"lat\": \"22.697476000\", \"lng\": \"120.276300000\" },\n\t{ \"name\": \"Okayama Aircraft Factory\", \"lat\": \"22.783417000\", \"lng\": \"120.262951000\" },\n\t{ \"name\": \"Kagi Airfield\", \"lat\": \"23.462837000\", \"lng\": \"120.392882000\" },\n\t{ \"name\": \"Mako Guard District\", \"lat\": \"23.562350000\", \"lng\": \"119.565423000\" },\n\t{ \"name\": \"Hokuto Airfield\", \"lat\": \"23.865039000\", \"lng\": \"120.441570000\" },\n\t{ \"name\": \"Karenko Airfield\", \"lat\": \"23.947430000\", \"lng\": \"121.590586000\" },\n\t{ \"name\": \"Shoka Airfield\", \"lat\": \"24.030368000\", \"lng\": \"120.487160000\" },\n\t{ \"name\": \"Taichu Airfield\", \"lat\": \"24.185598000\", \"lng\": \"120.653896000\" },\n\t{ \"name\": \"Taichu West Airfield\", \"lat\": \"24.264667000\", \"lng\": \"120.620581000\" },\n\t{ \"name\": \"Koryu Airfield\", \"lat\": \"24.631679000\", \"lng\": \"120.784134000\" },\n\t{ \"name\": \"Giran Airfield\", \"lat\": \"24.732934000\", \"lng\": \"121.752857000\" },\n\t{ \"name\": \"Shinchiku Airfield\", \"lat\": \"24.819547000\", \"lng\": \"120.938099000\" },\n\t{ \"name\": \"Taihoku Prison\", \"lat\": \"25.032306000\", \"lng\": \"121.525417000\" },\n\t{ \"name\": \"Taihoku General Government Building\", \"lat\": \"25.040000000\", \"lng\": \"121.511944000\" },\n\t{ \"name\": \"Matsuyama Airfield\", \"lat\": \"25.069444000\", \"lng\": \"121.551667000\" },\n\t{ \"name\": \"Taihoku Prisoner of War Camp No 6\", \"lat\": \"25.084444000\", \"lng\": \"121.543111000\" },\n\t{ \"name\": \"Tamsui Seaplane Base\", \"lat\": \"25.164430000\", \"lng\": \"121.447310000\" }\n];\n\/\/ Initialize the map (parameters: initial latitude, initial longitude, zoom level)\nvar mymap = L.map('mapdivTaiwan').setView([0, 0], 13);\n\/\/ Specify tiles\nL.tileLayer('https:\/\/stamen-tiles-{s}.a.ssl.fastly.net\/terrain\/{z}\/{x}\/{y}.{ext}', {\n\tattribution: 'Tiles <a href=\"http:\/\/stamen.com\">Stamen Design<\/a>, <a href=\"http:\/\/creativecommons.org\/licenses\/by\/3.0\">CC BY 3.0<\/a> &mdash; Data <a href=\"http:\/\/www.openstreetmap.org\/copyright\">OpenStreetMap<\/a>',\n\tsubdomains: 'abcd',\n\tminZoom: 0,\n\tmaxZoom: 18,\n\text: 'png'\n}).addTo(mymap);\n\/\/ Loops through the raw data, place a point on the map, and build an array of the points\nvar circleArray = [];\nfor (var i = 0; i < rawDataArray.length; i++) {\n\tvar rawData = rawDataArray[i];\n\tcircle = new L.circle([rawData[\"lat\"], rawData[\"lng\"]], {\n\t\tcolor: 'red',\n\t\tfillColor: '#f03',\n\t\tfillOpacity: 0.5,\n\t\tradius: 50\n\t}).addTo(mymap).bindPopup(L.popup({maxHeight:200}).setContent(rawData[\"name\"]));\n\tcircleArray.push(circle);\n}\n\/\/ Adjust the map view based on the array of points, so the map won't appear to be zoomed overly in or out\nvar group = new L.featureGroup(circleArray);\nmymap.fitBounds(group.getBounds());\n<\/script><\/p>\n<p>While this worked for 99% of maps found on WW2DB, I discovered a small problem with Leaflet in which the .fitBounds() method did not handle things well when a single data set contains points on both sides of the International Date Line.  To be fair, this is not truly a Leaflet problem; this issue is generally a headache across all mapping programs, although this is something I did not notice with Google Maps before.  Here is an example demonstrating said problem involving points located in the Territory of Alaska:<\/p>\n<div id=\"mapdivAlaska\" style=\"width: 400px; height: 400px;\"><\/div>\n<p><script>\nvar rawDataArray = [\n\t{ \"name\": \"American ships in Adak Harbor, Aleutian Islands, U...\", \"lat\": \"51.864181000\", \"lng\": \"-176.619528000\" },\n\t{ \"name\": \"US Navy PV-1 Ventura aircraft of Bombing Squadron ...\", \"lat\": \"51.869211000\", \"lng\": \"-176.645784000\" },\n\t{ \"name\": \"Lt Herb Hasenfus of the 54th Fighter Squadron stan...\", \"lat\": \"51.878056000\", \"lng\": \"-176.646111000\" },\n\t{ \"name\": \"Commodore Leslie Gehres standing at attention whil...\", \"lat\": \"51.878056000\", \"lng\": \"-176.646111000\" },\n\t{ \"name\": \"Commodore Leslie Gehres standing at attention whil...\", \"lat\": \"51.878056000\", \"lng\": \"-176.646111000\" },\n\t{ \"name\": \"Three Japanese Type A-class midget submarines wrec...\", \"lat\": \"51.972472000\", \"lng\": \"177.532258000\" },\n\t{ \"name\": \"Three Japanese Type A-class midget submarines wrec...\", \"lat\": \"51.972472000\", \"lng\": \"177.532258000\" },\n\t{ \"name\": \"PBY-5A Catalina patrol plane flying past Segula Is...\", \"lat\": \"51.986097000\", \"lng\": \"178.084025000\" },\n\t{ \"name\": \"Navy PV-1 Ventura patrol aircraft of Bombing Squad...\", \"lat\": \"52.374973000\", \"lng\": \"173.716188000\" },\n\t{ \"name\": \"Commodore Leslie Gehres inspecting a PV-1 Ventura ...\", \"lat\": \"52.824100000\", \"lng\": \"173.174833000\" },\n\t{ \"name\": \"A PV-1 Ventura of Bombing Squadron VB-139 after a ...\", \"lat\": \"52.824100000\", \"lng\": \"173.174833000\" },\n\t{ \"name\": \"A PV-1 Ventura of Bombing Squadron VB-139 after a ...\", \"lat\": \"52.824100000\", \"lng\": \"173.174833000\" },\n\t{ \"name\": \"Members of the USAAF 54th Fighter Squadron with so...\", \"lat\": \"52.824648000\", \"lng\": \"173.170588000\" },\n\t{ \"name\": \"A US Navy PV-1 Ventura patrol bomber of Bombing Sq...\", \"lat\": \"52.824648000\", \"lng\": \"173.170588000\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boats of Motor Torpedo Boa...\", \"lat\": \"52.826667000\", \"lng\": \"173.220000000\" },\n\t{ \"name\": \"US Navy Commodore Leslie Gehres, commander of Flee...\", \"lat\": \"52.832500000\", \"lng\": \"173.175556000\" },\n\t{ \"name\": \"American troops at Massacre Bay, Attu, Aleutian Is...\", \"lat\": \"52.835188000\", \"lng\": \"173.187742000\" },\n\t{ \"name\": \"US Army soldiers unloading LCPR and LCM type landi...\", \"lat\": \"52.835188000\", \"lng\": \"173.187742000\" },\n\t{ \"name\": \"American soldiers unloading landing craft on the b...\", \"lat\": \"52.835188000\", \"lng\": \"173.187742000\" },\n\t{ \"name\": \"USS Luce departed Massacre Bay, Attu, Aleutian Isl...\", \"lat\": \"52.836138000\", \"lng\": \"173.225018000\" },\n\t{ \"name\": \"B-24 bombing photo of Holtz Bay, Attu Island, Aleu...\", \"lat\": \"52.914000000\", \"lng\": \"173.156943000\" },\n\t{ \"name\": \"Two D3A1 carrier dive bombers from Junyo over Dutc...\", \"lat\": \"53.888889000\", \"lng\": \"-166.527222000\" },\n\t{ \"name\": \"Japanese naval shells exploding in the harbor at D...\", \"lat\": \"53.891178000\", \"lng\": \"-166.536745000\" },\n\t{ \"name\": \"A United States Navy patrol PBY Catalina turned up...\", \"lat\": \"53.896137000\", \"lng\": \"-166.543349000\" },\n\t{ \"name\": \"USS Salt Lake City at Dutch Harbor, Alaska, 29 Mar...\", \"lat\": \"53.899125000\", \"lng\": \"-166.522743000\" },\n\t{ \"name\": \"US Marines in a trench at Dutch Harbor, US Territo...\", \"lat\": \"53.901667000\", \"lng\": \"-166.531944000\" },\n\t{ \"name\": \"Map of installations in the Aleutian Island Area a...\", \"lat\": \"54.359349000\", \"lng\": \"-159.668070000\" },\n\t{ \"name\": \"B-26 Marauder with the 73rd Bomb Squadron armed wi...\", \"lat\": \"55.205278000\", \"lng\": \"-162.724444000\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boat PT-73 in Womens Bay, ...\", \"lat\": \"57.709956000\", \"lng\": \"-152.546806000\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boat PT-74 in Womens Bay, ...\", \"lat\": \"57.709956000\", \"lng\": \"-152.546806000\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boat PT-75 in Womens Bay, ...\", \"lat\": \"57.709956000\", \"lng\": \"-152.546806000\" },\n\t{ \"name\": \"US Navy personnel freeing a PBY-5A Catalina aircra...\", \"lat\": \"57.735875000\", \"lng\": \"-152.509466667\" },\n\t{ \"name\": \"Three Lockheed A-29 Hudsons fly past Mt McKinley, ...\", \"lat\": \"63.069500000\", \"lng\": \"-151.007400000\" }\n];\n\/\/ Initialize the map (parameters: initial latitude, initial longitude, zoom level)\nvar mymap = L.map('mapdivAlaska').setView([0, 0], 13);\n\/\/ Specify tiles\nL.tileLayer('https:\/\/stamen-tiles-{s}.a.ssl.fastly.net\/terrain\/{z}\/{x}\/{y}.{ext}', {\n\tattribution: 'Tiles <a href=\"http:\/\/stamen.com\">Stamen Design<\/a>, <a href=\"http:\/\/creativecommons.org\/licenses\/by\/3.0\">CC BY 3.0<\/a> &mdash; Data <a href=\"http:\/\/www.openstreetmap.org\/copyright\">OpenStreetMap<\/a>',\n\tsubdomains: 'abcd',\n\tminZoom: 0,\n\tmaxZoom: 18,\n\text: 'png'\n}).addTo(mymap);\n\/\/ Loops through the raw data, place a point on the map, and build an array of the points\nvar circleArray = [];\nfor (var i = 0; i < rawDataArray.length; i++) {\n\tvar rawData = rawDataArray[i];\n\tcircle = new L.circle([rawData[\"lat\"], rawData[\"lng\"]], {\n\t\tcolor: 'red',\n\t\tfillColor: '#f03',\n\t\tfillOpacity: 0.5,\n\t\tradius: 50\n\t}).addTo(mymap).bindPopup(L.popup({maxHeight:200}).setContent(rawData[\"name\"]));\n\tcircleArray.push(circle);\n}\n\/\/ Adjust the map view based on the array of points, so the map won't appear to be zoomed overly in or out\nvar group = new L.featureGroup(circleArray);\nmymap.fitBounds(group.getBounds());\n<\/script><\/p>\n<p>I developed a work-around for this.  Recall I used a PHP snippet to fetch data from the backend and to build the Javascript array for Leaflet to use.  I modified the PHP code so that as I looped through the data, I would also keep counts of points with really low (I used 120 or less) or really high (I used 120 or more) longitude values.  With this two counts, I could then have the PHP determine whether I would bring some points to the other side of the International Date Line by adding or subtracting 360 degrees to their longitude values.  At this time, I made that determination by evaluating the number of points that would remain\/would be moved.  For the case of Alaska, with this logic applied, the PHP code would decide that all data points with longitude value less than 120 will have 360 added to it; for example, (54.359349,-159.66807) will become (54.359349,200.33193).  After applying this work-around, the Alaska map becomes this:<\/p>\n<div id=\"mapdivAlaska2\" style=\"width: 400px; height: 400px;\"><\/div>\n<p><script>\nvar rawDataArray = [\n\t{ \"name\": \"American ships in Adak Harbor, Aleutian Islands, U...\", \"lat\": \"51.864181000\", \"lng\": \"183.380472\" },\n\t{ \"name\": \"US Navy PV-1 Ventura aircraft of Bombing Squadron ...\", \"lat\": \"51.869211000\", \"lng\": \"183.354216\" },\n\t{ \"name\": \"Lt Herb Hasenfus of the 54th Fighter Squadron stan...\", \"lat\": \"51.878056000\", \"lng\": \"183.353889\" },\n\t{ \"name\": \"Commodore Leslie Gehres standing at attention whil...\", \"lat\": \"51.878056000\", \"lng\": \"183.353889\" },\n\t{ \"name\": \"Commodore Leslie Gehres standing at attention whil...\", \"lat\": \"51.878056000\", \"lng\": \"183.353889\" },\n\t{ \"name\": \"Three Japanese Type A-class midget submarines wrec...\", \"lat\": \"51.972472000\", \"lng\": \"177.532258000\" },\n\t{ \"name\": \"Three Japanese Type A-class midget submarines wrec...\", \"lat\": \"51.972472000\", \"lng\": \"177.532258000\" },\n\t{ \"name\": \"PBY-5A Catalina patrol plane flying past Segula Is...\", \"lat\": \"51.986097000\", \"lng\": \"178.084025000\" },\n\t{ \"name\": \"Navy PV-1 Ventura patrol aircraft of Bombing Squad...\", \"lat\": \"52.374973000\", \"lng\": \"173.716188000\" },\n\t{ \"name\": \"Commodore Leslie Gehres inspecting a PV-1 Ventura ...\", \"lat\": \"52.824100000\", \"lng\": \"173.174833000\" },\n\t{ \"name\": \"A PV-1 Ventura of Bombing Squadron VB-139 after a ...\", \"lat\": \"52.824100000\", \"lng\": \"173.174833000\" },\n\t{ \"name\": \"A PV-1 Ventura of Bombing Squadron VB-139 after a ...\", \"lat\": \"52.824100000\", \"lng\": \"173.174833000\" },\n\t{ \"name\": \"Members of the USAAF 54th Fighter Squadron with so...\", \"lat\": \"52.824648000\", \"lng\": \"173.170588000\" },\n\t{ \"name\": \"A US Navy PV-1 Ventura patrol bomber of Bombing Sq...\", \"lat\": \"52.824648000\", \"lng\": \"173.170588000\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boats of Motor Torpedo Boa...\", \"lat\": \"52.826667000\", \"lng\": \"173.220000000\" },\n\t{ \"name\": \"US Navy Commodore Leslie Gehres, commander of Flee...\", \"lat\": \"52.832500000\", \"lng\": \"173.175556000\" },\n\t{ \"name\": \"American troops at Massacre Bay, Attu, Aleutian Is...\", \"lat\": \"52.835188000\", \"lng\": \"173.187742000\" },\n\t{ \"name\": \"US Army soldiers unloading LCPR and LCM type landi...\", \"lat\": \"52.835188000\", \"lng\": \"173.187742000\" },\n\t{ \"name\": \"American soldiers unloading landing craft on the b...\", \"lat\": \"52.835188000\", \"lng\": \"173.187742000\" },\n\t{ \"name\": \"USS Luce departed Massacre Bay, Attu, Aleutian Isl...\", \"lat\": \"52.836138000\", \"lng\": \"173.225018000\" },\n\t{ \"name\": \"B-24 bombing photo of Holtz Bay, Attu Island, Aleu...\", \"lat\": \"52.914000000\", \"lng\": \"173.156943000\" },\n\t{ \"name\": \"Two D3A1 carrier dive bombers from Junyo over Dutc...\", \"lat\": \"53.888889000\", \"lng\": \"193.472778\" },\n\t{ \"name\": \"Japanese naval shells exploding in the harbor at D...\", \"lat\": \"53.891178000\", \"lng\": \"193.463255\" },\n\t{ \"name\": \"A United States Navy patrol PBY Catalina turned up...\", \"lat\": \"53.896137000\", \"lng\": \"193.456651\" },\n\t{ \"name\": \"USS Salt Lake City at Dutch Harbor, Alaska, 29 Mar...\", \"lat\": \"53.899125000\", \"lng\": \"193.477257\" },\n\t{ \"name\": \"US Marines in a trench at Dutch Harbor, US Territo...\", \"lat\": \"53.901667000\", \"lng\": \"193.468056\" },\n\t{ \"name\": \"Map of installations in the Aleutian Island Area a...\", \"lat\": \"54.359349000\", \"lng\": \"200.33193\" },\n\t{ \"name\": \"B-26 Marauder with the 73rd Bomb Squadron armed wi...\", \"lat\": \"55.205278000\", \"lng\": \"197.275556\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boat PT-73 in Womens Bay, ...\", \"lat\": \"57.709956000\", \"lng\": \"207.453194\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boat PT-74 in Womens Bay, ...\", \"lat\": \"57.709956000\", \"lng\": \"207.453194\" },\n\t{ \"name\": \"Higgins 78-foot torpedo boat PT-75 in Womens Bay, ...\", \"lat\": \"57.709956000\", \"lng\": \"207.453194\" },\n\t{ \"name\": \"US Navy personnel freeing a PBY-5A Catalina aircra...\", \"lat\": \"57.735875000\", \"lng\": \"207.490533333\" },\n\t{ \"name\": \"Three Lockheed A-29 Hudsons fly past Mt McKinley, ...\", \"lat\": \"63.069500000\", \"lng\": \"208.9926\" }\n];\n\/\/ Initialize the map (parameters: initial latitude, initial longitude, zoom level)\nvar mymap = L.map('mapdivAlaska2').setView([0, 0], 13);\n\/\/ Specify tiles\nL.tileLayer('https:\/\/stamen-tiles-{s}.a.ssl.fastly.net\/terrain\/{z}\/{x}\/{y}.{ext}', {\n\tattribution: 'Tiles <a href=\"http:\/\/stamen.com\">Stamen Design<\/a>, <a href=\"http:\/\/creativecommons.org\/licenses\/by\/3.0\">CC BY 3.0<\/a> &mdash; Data <a href=\"http:\/\/www.openstreetmap.org\/copyright\">OpenStreetMap<\/a>',\n\tsubdomains: 'abcd',\n\tminZoom: 0,\n\tmaxZoom: 18,\n\text: 'png'\n}).addTo(mymap);\n\/\/ Loops through the raw data, place a point on the map, and build an array of the points\nvar circleArray = [];\nfor (var i = 0; i < rawDataArray.length; i++) {\n\tvar rawData = rawDataArray[i];\n\tcircle = new L.circle([rawData[\"lat\"], rawData[\"lng\"]], {\n\t\tcolor: 'red',\n\t\tfillColor: '#f03',\n\t\tfillOpacity: 0.5,\n\t\tradius: 50\n\t}).addTo(mymap).bindPopup(L.popup({maxHeight:200}).setContent(rawData[\"name\"]));\n\tcircleArray.push(circle);\n}\n\/\/ Adjust the map view based on the array of points, so the map won't appear to be zoomed overly in or out\nvar group = new L.featureGroup(circleArray);\nmymap.fitBounds(group.getBounds());\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article provides a working code sample for the implementation of OpenStreetMap using the Leaflet Javascript library and a Stamen map tiles set.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46],"tags":[],"class_list":["post-12","post","type-post","status-publish","format-standard","hentry","category-openstreetmap"],"_links":{"self":[{"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/posts\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":6,"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/posts\/12\/revisions"}],"predecessor-version":[{"id":280,"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/posts\/12\/revisions\/280"}],"wp:attachment":[{"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/media?parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/categories?post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dev-notes.com\/blog\/wp-json\/wp\/v2\/tags?post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}