Adding new paths to D3 Globe - javascript

I am working on an implementation of a D3 Globe. I am trying to add paths to the globe when the user clicks a button, but this is not proving successful. If I add all paths at once there is no issue, but if I try to add them after a trigger event then it fails. My jsfiddle: http://jsfiddle.net/Guill84/b6xvj76e/1/. I don't think there is an issue with the JSON, as it pops up in the console as expected.
The bit of the script that fails can be found right at the bottom of the fiddle. I paste it below for ease of reference:
$("#clickMe").click(function() {
data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"name": "path1"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[117.5977,44.3408],[116.4551,40.2539]]]"
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path2"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[122.3438,41.0889],[116.4551,40.2539]]]"
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path3"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[105.9961,37.3096],[116.4551,40.2539]]]"
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path4"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": "[[[116.4551,40.2539],[109.5996,35.6396],[116.4551,40.2539]]]"
},
"id": "RML"
}]}
console.log(data);
var svg = d3.select("#body");
flows = svg.selectAll("path")
.data(data)
.enter().append("svg:path")
.attr("d", clip)
.style("stroke", "black")
.attr("id", function(d) {
return d.properties.name.split(' ').join('_')
});
});

The problems are three:
1) Your JSON structure has a problem: the arrays are specified in string format, thus causing an error when used by the clip function.
2) You are binding the data object directly, when you should instead binding data.features which is the array which contains the four paths you need to create.
3) The selection will select the already existing paths for countries. You can avoid this by adding a class to the new paths. For example, classing them as flow.
4) The flows paths are declared inside the scope of their rendering function, therefore they cannot be updated on the refresh function.
Here's your code with the three fixes:
$("#clickMe").click(function () {
// 1) Arrays: Fixed arrays for coordinates so they are not serialized in a string
var data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "path1"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [117.5977, 44.3408], [116.4551, 40.2539]]]
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path2"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [122.3438, 41.0889], [116.4551, 40.2539]]]
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path3"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [105.9961, 37.3096], [116.4551, 40.2539]]]
},
"id": "RML"
},
{
"type": "Feature",
"properties": {
"name": "path4"
},
"year": "2010",
"geometry": {
"type": "Polygon",
"coordinates": [[[116.4551, 40.2539], [109.5996, 35.6396], [116.4551, 40.2539]]]
},
"id": "RML"
}
]
};
console.log(data);
var svg = d3.select("#body");
// 3) Selection: Add a class to avoid collision with existing paths
// 4) Using var declared outside so it can be used on the update function
flows = svg.selectAll("path.flow")
// 2) Data binding: Bind the features property instead, which is an array
.data(data.features);
// 3) Enter nodes: When appending them, class them as flow so they keep separated
flows.enter().append("svg:path")
.classed("flow", true)
.attr("d", clip)
.style("stroke", "black")
.style("stroke-width", "1px")
.attr("id", function (d) {
return d.properties.name.split(' ').join('_')
});
});
Now it works, but I still cannot see the added paths on the globe. The path elements are for sure appended to the DOM of the svg element, though, which solves your initial problem ;)
- UPDATE -
As indicated on the comments, the added paths didn't follow the movement of the globe. That was due to the paths being added to the svg but not updated along the country shapes on the refresh() function (added point 4).
To do so, the selection for these paths should be made available inside the refresh() function (it suffices declaring the var flows at the top of the script), and then adding an update for this selection inside that function. Like this:
function refresh(duration) {
(duration ? feature.transition().duration(duration) : feature).attr("d", clip);
// 4) Added the flows to the paths selection whose d attribute will be updated (only when present)
flows && (duration ? flows.transition().duration(duration) : flows).attr("d", clip);
}
A complete version can be seen on this fiddle: http://jsfiddle.net/oscar_dr/0psy5udk/2/

Related

How to convert JSON to GeoJson JavaScript

I've got a JSON from a database but now I need to convert it into GeoJson to use it in my map
I found this solution but it shows an undefined array.
$.getJSON("./origin/neworigin.json", function(jsonData) {
var outGeoJson = {}
outGeoJson['properties'] = jsonData
outGeoJson['type']= "Feature"
outGeoJson['geometry']= {"type": "Point", "coordinates":
[jsonData['latitude'], jsonData['longitude']]}
console.log(outGeoJson)
});
This is an example from myJSON
[{"station":"BORJA","institution":"SENCICO","longitude":"-77.0064","latitude":"-12.0855"},
{"station":"SCARQ","institution":"SENCICO","longitude":"-71.5408","latitude":"-16.385"},
{"station":"SCAR2","institution":"SENCICO","longitude":"-71.5364","latitude":"-16.3934"},...
in browser
Check if the array is empty or not.
Try change the variable names.
OR
Provide more details.
You have two options to create a valid GeoJSON form JSON.
create GeoJSON.Point array and GeoJSON.FeatureCollection
create GeoJSON.MultiPoint object
Here are code snippets:
const jsonData = [{
"station": "BORJA",
"institution": "SENCICO",
"longitude": "-77.0064",
"latitude": "-12.0855"
},
{
"station": "SCARQ",
"institution": "SENCICO",
"longitude": "-71.5408",
"latitude": "-16.385"
},
{
"station": "SCAR2",
"institution": "SENCICO",
"longitude": "-71.5364",
"latitude": "-16.3934"
}
];
// to GeoJSON.Point array
const geoJSONPointArr = jsonData.map(row => {
return {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [row.longitude, row.latitude]
},
"properties": row
}
});
console.log(geoJSONPointArr);
// to GeoJSON.FeatureCollection
const pointArrFeatureCollection = {
"type": "FeatureCollection",
"features": geoJSONPointArr
}
console.log(pointArrFeatureCollection);
// to GeoJSON.MultiPoint
const geoJSONMultiPoint = {
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": jsonData.map(row => [row.longitude, row.latitude])
},
"properties": {
originalData: jsonData
}
}
console.log(geoJSONMultiPoint);
I would also recommend using the turf library, which is very convenient when working with the GeoJSON format.

How to make MarkerClusterGroup cluster polygons

I am trying to show clusters using markerclustergroups with Polygons. Right now the polygons are shown but the clusters aren't. I have been trying to use center of mass for the polygons because it seems like markerclustergroup doesn't like polygons but that doesn't really work since the animation of markerclustergroup will be set on the centroids and not the actual polygon.
My polygons all vary in amount of coordinates. Some have +10 sets others have 3.
How would I use markerclustergroup for polygons?
Below my code can be seen:
// Create variable to hold map element, give initial settings to map
var map = L.map('map', {
center: [23.70489, 43.90137],
zoom: 5
});
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
}).addTo(map);
var ojStyle = {
"color": "#ff7800",
"weight": 5,
"opacity": 0.65
};
// Hardcoded polygons as GeoJSON
var polygons = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[37.99896240234376, 21.55017532555692],
[39.39422607421876, 21.476073444092435],
[38.88336181640626, 22.56582956966297],
[38.023681640625, 22.611475436593366],
[37.43591308593751, 21.99908185836153],
[37.28485107421876, 21.624239377938288],
[37.28485107421876, 21.624239377938288],
[37.99896240234376, 21.55017532555692]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[38.50708007812501, 21.453068633086783],
[39.20745849609376, 21.37124437061832],
[39.10858154296876, 20.876776727727016],
[38.80920410156251, 20.912700155617568],
[38.49884033203126, 20.94604992010052],
[38.50708007812501, 21.453068633086783]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[50.57830810546875, 25.980268007469803],
[50.77606201171876, 25.956809920555312],
[50.780181884765625, 25.69970044378398],
[50.56457519531251, 25.822144306879686],
[50.56182861328126, 25.945696562830516],
[50.57830810546875, 25.980268007469803]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[54.37408447265626, 24.51963836811676],
[54.29443359375001, 24.40963901896311],
[54.25872802734375, 24.449649897759667],
[54.32739257812501, 24.539627918861232],
[54.37133789062501, 24.559614286039903],
[54.37408447265626, 24.51963836811676]
]
]
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[54.40155029296876, 24.463400705082282],
[54.41940307617188, 24.489648077028683],
[54.45785522460938, 24.462150693715266],
[54.43450927734376, 24.43839812102505],
[54.40155029296876, 24.463400705082282]
]
]
}
}]
}
var polygonArray = []
for (i = 0; i < polygons.features.length; i++) {
polygonArray.push(polygons.features[i]);
}
var markers = L.markerClusterGroup().addTo(map);
var geoJsonLayer = L.geoJson(polygonArray);
markers.addLayer(geoJsonLayer);
map.fitBounds(markers.getBounds());
http://js.do/code/165930 - Shows how clustering doesn't work for the polygons
I am looking for a solution like this: http://jsfiddle.net/ve2huzxw/237/
You can do it very much like in this GIS post: Is it possible to cluster polygons in Leaflet?
// Compute a polygon "center", use your favourite algorithm (centroid, etc.)
L.Polygon.addInitHook(function() {
this._latlng = this._bounds.getCenter();
});
// Provide getLatLng and setLatLng methods for
// Leaflet.markercluster to be able to cluster polygons.
L.Polygon.include({
getLatLng: function() {
return this._latlng;
},
setLatLng: function() {} // Dummy method.
});
Updated live example: http://js.do/code/166021

Trying to create a map with D3, but it isn't showing up

I'm trying to draw a map of Asia using d3. I followed this tutorial with ended with the following example: http://maptimeboston.github.io/d3-maptime/example3/index.html
So I decided to try and adapt that example for my purposes. I got the Asia data from here: https://github.com/codeforamerica/click_that_hood/blob/master/public/data/asia.geojson
So my neighborhoods.js code now looks like this (not entire file included):
var neighborhoods_json = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"name": "Cyprus",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-04T08:41:12+0100",
"cartodb_id": 27
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[33.973617, 35.058506],
[34.004881, 34.978098],
[32.979827, 34.571869],
[32.490296, 34.701655],
[32.256667, 35.103232],
[32.73178, 35.140026],
[32.919572, 35.087833],
[33.190977, 35.173125],
[33.383833, 35.162712],
[33.455922, 35.101424],
[33.475817, 35.000345],
[33.525685, 35.038688],
[33.675392, 35.017863],
[33.86644, 35.093595],
[33.973617, 35.058506]
]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "Georgia",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-04T08:41:12+0100",
"cartodb_id": 75
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[41.554084, 41.535656],
[41.703171, 41.962943],
[41.45347, 42.645123],
[40.875469, 43.013628],
[40.321394, 43.128634],
[39.955009, 43.434998],
[40.076965, 43.553104],
[40.922185, 43.382159],
[42.394395, 43.220308],
[43.756017, 42.740828],
[43.9312, 42.554974],
[44.537623, 42.711993],
[45.470279, 42.502781],
[45.77641, 42.092444],
[46.404951, 41.860675],
[46.145432, 41.722802],
[46.637908, 41.181673],
[46.501637, 41.064445],
[45.962601, 41.123873],
[45.217426, 41.411452],
[44.97248, 41.248129],
[43.582746, 41.092143],
[42.619549, 41.583173],
[41.554084, 41.535656]
]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "Nepal",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-04T08:41:12+0100",
"cartodb_id": 121
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[88.120441, 27.876542],
[88.043133, 27.445819],
[88.174804, 26.810405],
[88.060238, 26.414615],
[87.227472, 26.397898],
[86.024393, 26.630985],
[85.251779, 26.726198],
[84.675018, 27.234901],
[83.304249, 27.364506],
[81.999987, 27.925479],
[81.057203, 28.416095],
[80.088425, 28.79447],
[80.476721, 29.729865],
[81.111256, 30.183481],
[81.525804, 30.422717],
[82.327513, 30.115268],
[83.337115, 29.463732],
[83.898993, 29.320226],
[84.23458, 28.839894],
[85.011638, 28.642774],
[85.82332, 28.203576],
[86.954517, 27.974262],
[88.120441, 27.876542]
]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "Palestine",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-04T08:41:12+0100",
"cartodb_id": 4
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[35.545665, 32.393992],
[35.545252, 31.782505],
[35.397561, 31.489086],
[34.927408, 31.353435],
[34.970507, 31.616778],
[35.225892, 31.754341],
[34.974641, 31.866582],
[35.18393, 32.532511],
[35.545665, 32.393992]
]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "Qatar",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-04T08:41:12+0100",
"cartodb_id": 13
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[50.810108, 24.754743],
[50.743911, 25.482424],
[51.013352, 26.006992],
[51.286462, 26.114582],
[51.589079, 25.801113],
[51.6067, 25.21567],
[51.389608, 24.627386],
[51.112415, 24.556331],
[50.810108, 24.754743]
]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "South Korea (Republic of Korea)",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-29T19:58:09+0100",
"cartodb_id": 102
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[128.349716, 38.612243],
[129.21292, 37.432392],
[129.46045, 36.784189],
[129.468304, 35.632141],
[129.091377, 35.082484],
[128.18585, 34.890377],
[127.386519, 34.475674],
[126.485748, 34.390046],
[126.37392, 34.93456],
[126.559231, 35.684541],
[126.117398, 36.725485],
[126.860143, 36.893924],
[126.174759, 37.749686],
[126.237339, 37.840378],
[126.68372, 37.804773],
[127.073309, 38.256115],
[127.780035, 38.304536],
[128.205746, 38.370397],
[128.349716, 38.612243]
]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "Sri Lanka",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-04T08:41:12+0100",
"cartodb_id": 108
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[81.787959, 7.523055],
[81.637322, 6.481775],
[81.21802, 6.197141],
[80.348357, 5.96837],
[79.872469, 6.763463],
[79.695167, 8.200843],
[80.147801, 9.824078],
[80.838818, 9.268427],
[81.304319, 8.564206],
[81.787959, 7.523055]
]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "Afghanistan",
"created_at": "2013-12-04T08:41:11+0100",
"updated_at": "2013-12-04T08:41:12+0100",
"cartodb_id": 16
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[61.210817, 35.650072],
[62.230651, 35.270664],
[62.984662, 35.404041],
[63.193538, 35.857166],
[63.982896, 36.007957],
[64.546479, 36.312073],
[64.746105, 37.111818],
[65.588948, 37.305217],
[65.745631, 37.661164],
[66.217385, 37.39379],
[66.518607, 37.362784],
[67.075782, 37.356144],
[67.83, 37.144994],
[68.135562, 37.023115],
[68.859446, 37.344336],
[69.196273, 37.151144],
[69.518785, 37.608997],
[70.116578, 37.588223],
[70.270574, 37.735165],
[70.376304, 38.138396],
[70.806821, 38.486282],
[71.348131, 38.258905],
[71.239404, 37.953265],
[71.541918, 37.905774],
[71.448693, 37.065645],
[71.844638, 36.738171],
[72.193041, 36.948288],
[72.63689, 37.047558],
[73.260056, 37.495257],
[73.948696, 37.421566],
[74.980002, 37.41999],
[75.158028, 37.133031],
[74.575893, 37.020841],
[74.067552, 36.836176],
[72.920025, 36.720007],
[71.846292, 36.509942],
[71.262348, 36.074388],
[71.498768, 35.650563],
[71.613076, 35.153203],
[71.115019, 34.733126],
[71.156773, 34.348911],
[70.881803, 33.988856],
[69.930543, 34.02012],
[70.323594, 33.358533],
[69.687147, 33.105499],
[69.262522, 32.501944],
[69.317764, 31.901412],
[68.926677, 31.620189],
[68.556932, 31.71331],
[67.792689, 31.58293],
[67.683394, 31.303154],
[66.938891, 31.304911],
[66.381458, 30.738899],
[66.346473, 29.887943],
[65.046862, 29.472181],
[64.350419, 29.560031],
[64.148002, 29.340819],
[63.550261, 29.468331],
[62.549857, 29.318572],
[60.874248, 29.829239],
[61.781222, 30.73585],
[61.699314, 31.379506],
[60.941945, 31.548075],
[60.863655, 32.18292],
[60.536078, 32.981269],
[60.9637, 33.528832],
[60.52843, 33.676446],
[60.803193, 34.404102],
[61.210817, 35.650072]
]
]
]
}
}
And I didn't change the original html file, which looks like this:
<html>
<head>
<title>A D3 map</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="neighborhoods.js"></script>
</head>
<body>
<script>
var width = 2000,
height = 2000;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.append("g");
var albersProjection = d3.geo.albers()
.scale(190000)
.rotate([71.057, 0])
.center([0, 42.313])
.translate([width / 2, height / 2]);
var geoPath = d3.geo.path()
.projection(albersProjection);
g.selectAll("path")
.data(neighborhoods_json.features)
.enter()
.append("path")
.attr("fill", "#ccc")
.attr("d", geoPath);
</script>
</body>
</html>
So my question is:
I don't know where things go wrong. When I inspect the page it clearly shows that paths are being created, they just aren't shown ):
Does anybody have any clue what stupid thing I am doing wrong.
Your map is drawing as expected.
Let's look at the projection:
var albersProjection = d3.geo.albers()
.scale(190000)
.rotate([71.057, 0])
.center([0, 42.313])
.translate([width / 2, height / 2]);
This is an albers projection, it is centered on [-71.057,42.313] (degrees longitude and latitude respectively), this is Boston (which I believe your example is of). The scale factor is huge, which means it is very zoomed in (a value of 200 or so might show the whole world), so it likely shows only the area around Boston.
Your data is in Asia - including features such as South Korea and Qatar. These features will not be visible using this projection (As you state, if you inspect the svg, you will see that features are drawn, just with odd coordinates that are beyond the edges of the svg).
You need to update your projection to show the area you are focusing on. If you want to keep an Albers projection, then you should also set the parallels (by default they are best suited for the US).
I tested your data with the following projection:
var albersProjection = d3.geo.albers()
.scale(600)
.rotate([-65, 0])
.center([0, 33])
.translate([width / 2, height / 2]);
(I also changed the width and height to 1000 so it fit better on my screen).
This projection is centered on [65,33] (degrees longitude, latitude respectively).
This gave me:
I used a negative rotation value for the x axis because I'm spinning the globe under me, not rotating my viewpoint.
I was just eyeballing the countries in the list and trying to find a center point in google earth, you could do much better, even programmatically finding the center.
I didn't set the parallels, but to do so, find two parallels that intersect your area of interest and set them using:
projection.parallels([a,b])
A more detailed examination of albers projection parameters and d3 can be found in this answer.
If you are uncertain where your features are relative to your svg, try zooming out, lower zoom values will show more of the earth, and hopefully will reveal where your hidden features are residing (this can help narrow down the sources of the problem when features are missing).

Openlayers 3 z-ordering of features

I have a vector layer, which contains polygons and points loaded from GEOJSON source. It looks to me, points are always positioned above polygons regardless of their order in source GEOJSON file. See an example definition below. Is there a way, how to position points below polygons on the same layer?
The example:
Points are styled as white and red circle. Polygon is gray.
My GEOJSON looks like this (I even tried to reverse features order in the file):
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"radius": "1000"
},
"geometry": {
"type": "Point",
"coordinates": [
12.4,
50.08333
]
}
},
{
"type": "Feature",
"properties": {
"radius": "800"
},
"geometry": {
"type": "Point",
"coordinates": [
12.4,
50.08333
]
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[
12.4,
50.08333
],
...........
Use zIndex in the style objects.

Parent polygon in Leaflet js

I would like to wrap multiple polygons in a parent polygon. Example below:
Is this possible in Leaflet js? Assume I have an array of L.polygon objects.
Thank you
Short answer: no.
If you want to create an envelope for your polygones, then it is an algorithm problem that goes beyond the scope of leafletjs.
You can look at the answers of this question to start solving your problem.
EDIT: here is an example using Turfjs library (thanks to #IvanSanchez for the heads up and to #HudsonPH for the polygons).
// draw envelope
var points = {
"type": "FeatureCollection",
"features":
[
// collect the points of your polygons
turf.point([-104.05, 48.99]),
// ...
]
};
var hull = turf.convex(points);
L.geoJson(hull).addTo(map);
You can have a group, but you need define all the coordinates
more info: http://leafletjs.com/examples/geojson.html
var states = [{
"type": "Feature",
"properties": {"party": "Republican"},
"geometry": {
"type": "Polygon",
"coordinates": [[
[-104.05, 48.99],
[-97.22, 48.98],
[-96.58, 45.94],
[-104.03, 45.94],
[-104.05, 48.99]
]]
}
}, {
"type": "Feature",
"properties": {"party": "Democrat"},
"geometry": {
"type": "Polygon",
"coordinates": [[
[-109.05, 41.00],
[-102.06, 40.99],
[-102.03, 36.99],
[-109.04, 36.99],
[-109.05, 41.00]
]]
}
}];
L.geoJson(states, {
style: function(feature) {
switch (feature.properties.party) {
case 'Republican': return {color: "#ff0000"};
case 'Democrat': return {color: "#0000ff"};
}
}
}).addTo(map);

Categories