Rendering geoJSON using D3 and Leaflet using imageOverlay - d3.js

Quick version: I’m having trouble displaying a d3 element on a static image displayed by Leaflet. It works if I use d3noob’s (http://bl.ocks.org/d3noob/9211665) example…but I’m having trouble extending it. I’m guessing it’s because of the lang and long translation or the projection but I’m not sure what I need to change. I’m trying to display the geoJSON in the centre of the image (my code on JSFiddle: https://jsfiddle.net/g_at_work/qyhf0qz0/12/)
Longer version:
I'm trying to extend d3noob’s example so that I can display geoJSON on static images using Leaflet and D3 (an requirement from my boss unfortunately). I was able to reproduce d3noob’s tile based example but I've had trouble with the static version.
I've been able to display the static image but I've not been able to display the blue rectangle on the image. I'm not sure what I need to do to manipulate the position of the blue rectangle described in the JSON.
I've tried playing around with setting the coordinates in the projectPoint function but no luck:
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
At this stage I’m thinking I need to describe a new projection but I’m not sure what.
Here is the code which I’m using to display the static image:
var map = new L.Map("map", {maxZoom:1,center: [0,0], zoom: 3,crs:L.CRS.Simple});
var southWest = map.unproject([0,882],map.getMaxZoom());
var northEast = map.unproject([1085,0],map.getMaxZoom());
var imageBounds = new L.LatLngBounds(southWest,northEast);
L.imageOverlay('http://www.w3schools.com/css/trolltunga.jpg',imageBounds).addTo(map);
map.fitBounds(imageBounds);
It would be great if someone could suggest a strategy for maniuplating the position of the rectangle (I’m new to d3 and leaflet)
Thanks a bunch
G

so after some tinkering I found that creating a new projection enabled me to set the location and scale the map so I could place it where I needed it to be :
var center = d3.geo.centroid(geoShapeInstance);
var scale = [800000];
var offset = [175, 1];
var projection = d3.geo.mercator().scale(scale).center(center).translate(offset);
var path = d3.geo.path().projection(projection);
Fiddling with the 'offset' variable allowed me to set the location and playing with the 'scale' variable allowed me to resize the map (scale is a [x,x] value)
Hope this helps someone.

Related

Centering `text-geometry` text

I'm working on a project on 8th Wall using A-Frame and Three.js.
I'm using a component called "text-geometry" which generates extruded text nicely. But I want the text to be centered, not "flush-left", so I need to move it left by half its rendered width. I'm doing this using a bounding box:
bbox = new THREE.Box3().setFromObject(mesh)
el.object3D.position.x = (bbox.min.x - bbox.max.x) / 2
The problem is that if the text is nested within several levels of a-entities each with its own scale, the centering is incorrect.
So I am crawling up through all nested entities to find the "true scale":
let [trueScale, ee] = [1, el]
while (ee.parentElement) {
const scale = ee.getAttribute('scale')
if (scale) { trueScale *= scale.x }
ee = ee.parentElement
}
This seems inefficient – is there a more elegant way to do this so that my bbox returns the correct width accounting for the 'effective' scale of the text entity?

keep the center of a sprite fixed while rotating

I'm using Cocos2d-js v3 to create a jackpot-spinner. When I'm rotating the spinner wheel sprite, it wobbles, as in it moves in x,y axis slightly too while rotataing. How can I keep the sprite fixed while rotating? I'm new to Cocos2d-js.
Here is my creating the sprite code -
sprite = new cc.Sprite.create(res.wheel_png);
sprite.setPosition(cc.p(size.width/2, size.height/2));
this.addChild(sprite, 0);
And rotation code -
var rand = Math.random();
var sprite_action = cc.RotateBy.create(2, 1370);
var repeat_action = cc.Repeat.create(sprite_action, rand);
sprite.runAction(repeat_action);
Create method is deprecated, as are some others. Check out this page for list of all things deprecated.
As per the cocos docs for v3, (look up "rotateby")
Field Detail <static> {cc.RotateBy} cc.RotateBy.create
Please use cc.rotateBy instead. Rotates a cc.Node object clockwise a number of degrees by modifying it's rotation attribute. Relative to its properties to modify.
Deprecated:since v3.0
Please use cc.rotateBy instead.
You need to use it like this:
var rand = Math.random();
var sprite_action = cc.rotateBy(2, 1370);
var repeat_action = cc.repeat(sprite_action, rand);
sprite.runAction(repeat_action);

Using HTML Canvas to make a Choropleth Map

I attempting to make a Choropleth Map using HTML Canvas. If you are unfamiliar with Choropleth Maps they are basically a map that has different regions shaded with different colors. What I am trying to do is use the canvas fill() method to color different states on the US map. However, fill seems to only work if I have drawn an outline on my canvas.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
Here I want to put something like var c =ctx.fillMap(); however this won't work as Map is the entire US map and I just want to fill in a single state.

How to hide a html overlay label on a sphere object

I have a sphere model along with html text labels overlayed onto it at fixed positions. How can I hide them when they are behind the object when i am rotating my sphere using orbit controls?
Anyone knows about any references on stackoverflow or any examples which can solve my issue?
See this example how you could do it: http://jsfiddle.net/L0rdzbej/194/
I have put the relevant code in the updateLabelVisibility()-function, it looks like this:
var meshPosition = mesh.getWorldPosition();
var eye = camera.position.clone().sub( meshPosition );
var dot = eye.clone().normalize().dot( meshPosition.normalize() );
//IS TRUE WHEN THE MESH IS OCCLUDED BY THE SPHERE = dot value below 0.0
var ocluded = dot < -0.2;
if ( ocluded ) {
// HIDE LABEL IF CAMERA CANT SEE IT (I.E. WHEN IT IS BEHIND THE GLOBE)
label.style.visibility = "hidden";
}
else {
// DISPLAY LABEL IF MESH IS VISIBLE TO THE CAMERA
label.style.visibility = "visible";
}
Where mesh is the marker where your label is attached to. The dot is basically telling you how far around the sphere it is, within a certain distance of 90 degree. Simply said by values below zero the label is longer visible by going further around the back.
To be fair I based this off some code from: https://zeitgeist-globe.appspot.com/

Openlayers WMS layer not zooming properly

I developed an script to display 2 layers ob base map.
but it is not zooming properlly.
I am using following code
can you please suggest me
<script type="text/javascript">
var map, layer, select, hover, control;
function init(){
map = new OpenLayers.Map('map', {
controls: [
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.Permalink(),
new OpenLayers.Control.Navigation()
]
});
layer = new OpenLayers.Layer.WMS(
"States WMS/WFS",
"http://localhost:8080/geoserver/topp/wms",
{layers: 'topp:india_road',transparent: true}
);
select = new OpenLayers.Layer.Vector("Selection", {styleMap:
new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"])
});
hover = new OpenLayers.Layer.Vector("Hover");
map.addLayers([layer, hover, select]);
var wmsLayer = new OpenLayers.Layer.Google('Google Layer',{} );
map.addLayer(wmsLayer);
map.setCenter(new OpenLayers.Bounds(143.83482400000003,-43.648056,148.47914100000003,-39.573891).getCenterLonLat(), 5);
}
</script>
What do you mean by not zooming properly?
Are you finding that they are not matching up with the google maps when zooming in as far as you can go, or the zoom work until you try to pan and then the layers don't stay lined up with google maps? If this is the case then you are probably zooming in further than is supported by the Google map service. There is no easy way to fix this and I recommend you alter allowed scales and zoom with the following settings
minScale - float -- the minimum scale value at which the layer should display
maxScale - float -- the maximum scale value at which the layer should display
numZoomLevels - int -- Total number of zoom levels
Also please see this link on more information about google zoom scales.
If you are finding that none of your layers match the google background. I.E. they look like they are zoomed in out or offset then it is likely that your data is in a different projection to the google maps layer. Google maps uses EPSG:900913 as their SRS. The eisiest way to do this is to let geoserver do the re projection for you. Go to your layer setting in geoserver make sure you have the native projection set correctly and set the declared SRS to EPSG:900913.
If that doesn't help then I think we need more information on exactly what the problem is.

Resources