blob: 61d4eba948edfedf61cbceb172d22dd68b7f36ed [file]
var width = 800;
var height = 400;
var drag = false;
// using natural earth projection
// https://github.com/mbostock/d3/wiki/Geo-Projections
// http://bl.ocks.org/mbostock/4479477
var projection = d3.geo.naturalEarth()
.translate([width / 2, height / 2])
.precision(0.1)
.scale(140);
// used to scale mouse domain to rotation range
var scale_angle = d3.scale.linear()
.domain([-width, width])
.range([-180, 180]);
// tracks previous values
var prev_x = 0;
var prev_a = 0;
// geographic path generator (use instead of scales
// to map longitude, latitude points to pixel points)
var geo_path = d3.geo.path().projection(projection);
function draw_map() {
// generate svg image
var svg = d3.select("#map")
.append("svg")
.attr("width", width)
.attr("height", height);
var grid = d3.geo.graticule();
// create map background area
// https://github.com/mbostock/d3/wiki/Geo-Paths
svg.append("path")
.datum({type: "Sphere"})
.attr("d", geo_path)
.style("fill", "#93C2FF");
// create map grid
// https://github.com/mbostock/d3/wiki/Geo-Paths#wiki-graticule
// graticule: grid of intersecting latitude and longitude lines
svg.append("path")
.datum(d3.geo.graticule())
.attr("d", geo_path)
.style("fill", "none")
.style("stroke", "#ffffff")
.style("stroke-width", "0.5px");
// add ability to update projection
svg.on("mousedown", function() {
drag = true;
prev_x = d3.mouse(this)[0];
});
svg.on("mouseup", function() {
drag = false;
});
svg.on("mousemove", function() {
if (drag) {
curr_x = d3.mouse(this)[0];
curr_a = prev_a + scale_angle(curr_x - prev_x);
prev_x = curr_x;
prev_a = curr_a;
projection.rotate([curr_a, 0]);
update();
}
});
}
function draw_regions(data) {
// get pointer to svg image
var svg = d3.select("#map").select("svg"); //d3.select("svg")
// draw land masses
svg.append("path")
.datum(topojson.object(data, data.objects.land))
.attr("d", geo_path)
.style("fill", "#eeeeee")
.style("stroke", "none");
// draw region mesh, filter prevents drawing outer regions
// https://github.com/mbostock/topojson/wiki/Client-API-Reference#wiki-topojson_mesh
svg.append("path")
.datum(topojson.mesh(data, data.objects.countries, function(a, b) { return a !== b; }))
.attr("d", geo_path)
.style("fill", "none")
.style("stroke", "#999999")
.style("stroke-width", "0.5px");
// place map outline on top of map grid and regions
svg.append("path")
.datum({type: "Sphere"})
.attr("d", geo_path)
.style("fill", "none")
.style("stroke", "#444444")
.style("stroke-width", "1.5px");
}
function getColor(val, max){
factor = val / max;
if (factor < 0.1) {
return "rgb(165,0,38)"
} else if (factor < 0.2) {
return "rgb(215,48,39)"
} else if (factor < 0.3) {
return "rgb(244,109,67)"
} else if (factor < 0.4) {
return "rgb(253,174,97)"
} else if (factor < 0.5) {
return "rgb(254,224,139)"
} else if (factor < 0.6) {
return "rgb(255,255,191)"
} else if (factor < 0.7) {
return "rgb(217,225,139)"
} else if (factor < 0.8) {
return "rgb(166,225,106)"
} else if (factor < 0.9) {
return "rgb(102,225,99)"
} else {
return "rgb(26,225,80)";
//rgb(0,104,55)
}
}
// must be named this way to match earthquake feed
function show_geo_points(data) {
// get pointer to svg image
var svg = d3.select("#map").select("svg");
// handling updates are difficult
// http://bost.ocks.org/mike/join/
// http://bl.ocks.org/mbostock/3808234
//Assumption : max value is in first item
max = data[0].count;
//console.log(JSON.stringify(data));
// get any existing circles
var quakes = svg.selectAll("circle")
.data(data);
var radius = d3.scale.pow()
.range([2, 12])
.domain([0, 10]);
// add new circles for new earthquakes
quakes.enter()
.append("circle")
.attr("cx", function(d) {
var longitude = d.lon;
var latitude = d.lat;
return projection([longitude, latitude])[0];
})
.attr("cy", function(d) {
var longitude = d.lon;
var latitude = d.lat;
return projection([longitude, latitude])[1];
})
.attr("r", function(d) {
return 0;
})
.style("fill", function(d){
return getColor(d.count, max);
})
.style("fill-opacity", 0)
.style("stroke", 'rgb(255, 0, 0)')
.style("stroke-width", "0.5px")
.style("stroke-opacity", 1)
.transition()
.delay(function(d, i) {
return i / data.length * 100;
})
.duration(100)
.attr("r", function(d) {
return radius(0.01 + Math.log(d.count)/2);
//return radius(d.count);
})
.style("fill-opacity", 0.25);
// remove circles for old earthquakes no longer in data
quakes.exit()
.transition()
.attr("r", 0)
.style("fill-opacity", 0)
.remove();
}
function update() {
var svg = d3.select("#map").select("svg")
svg.selectAll("path").attr("d", geo_path);
svg.selectAll("circle")
.attr("cx", function(d) {
var longitude = d.lon;
var latitude = d.lat;
return projection([longitude, latitude])[0];
})
.attr("cy", function(d) {
var longitude = d.lon;
var latitude = d.lat;
return projection([longitude, latitude])[1];
});
}
function refreshGeomap(qry, topN, dtRange){
console.log(">Search Q=" + qry + "topN:"+ topN + ", date:" + dtRange);
if (!qry) {
qry = "*:*"
}
if (topN<0){
topN=1
}else{
topN++;
}
// var myString = "/q=<strong>"+ qry + "</strong>&fq=dates:<strong>"+ dtRange + "</strong>&facet=true&facet.mincount=1&facet.field=location_latlons&facet.field=cities&facet.limit=<strong>"+ topN + "</strong>&rows=0";
// $("#queryString").html(myString);
d3.json(SOLR_URL + "/query?q="+ qry + "&fq=dates:"+ dtRange + "&facet=true&facet.mincount=1&facet.field=location_latlons&facet.field=cities&facet.limit="+ topN + "&rows=0",
function(error, json) {
if (error) { return console.warn(error) }
facets = getSolrFacet(json, 'location_latlons', geoPointTransform);
places = getSolrFacet(json, 'cities');
list = $('#locationnames');
list.empty();
if (places.length == 0 ) {
console.log("No results found")
return
}
if (facets.length > 0 && places[0].term == 'Etc Hotel') {
places.splice(0, 1);
facets.splice(0, 1);
}
show_geo_points(facets);
for(var i=0; i<places.length && i < 40; i++) {
list.append("<li>" + places[i].term + "(" + places[i].count + ")</li>")
}
})
}