d3.js mercator projection to NYC map - dictionary

I am making a map of the boroughs in NYC and I can't seem to get the projection right: the only thing I get is a tiny map.
I tried recreating this example, which only made the console go crazy with errors, I suspect because there was something off about the equation.
When I was trying to get albers to work, I tried out the answer to this question, and still I could not get the map to work.
With 960/500 height and width, I used: var projection = d3.geo.albers().center([40.71, 73.98]).parallels([29.5, 45.5]).scale(10000).translate([(width) / 2, (height)/2]);
Right now, I am using a transverse Mercator, with the code below, and the topojson I created using one of these files.
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("nyc-borough.json", function(error, nyb) {
var boroughs = topojson.feature(nyb, nyb.objects["nyc-borough-boundaries-polygon"]).features;
var projection = d3.geo.transverseMercator()
.scale(1600)
.rotate([73 + 58 / 60, -48 - 47 / 60]);
var path = d3.geo.path()
.projection(projection);
var g = svg.append("g");
g.append("g")
.attr("id", "boroughs")
.selectAll(".state")
.data(boroughs)
.enter().append("path")
.attr("class", function(d){ return d.properties.name; })
.attr("d", path);
});
Please, please halp :(
Thanks in advance!

I created a bl.ock with the NYC boroughs here. You were on the right path with WSG84/Mercator as that was what the original data was in, as a quick check in QGIS demonstrated.
QGIS was also good checking the centre of the data, again which came out to be [-73.94, 40.70]. Note that these are the opposite way round to your co-ordinates which were lat and long, but d3 needs long and lat as discussed here in the API. The other thing to look out for is the negatives. North is positive so latitude in the northern hemisphere is positive and negative in the southern hemisphere. For the east and west hemispheres its east that's positive. Of course this only matters for the global projections the USA Albers wouldn't have negatives for the USA. Oh, and no discussion on Projections would be complete without a look at Jason Davies work.
If you want to use a different projection to the projection your data is in I generally think it's better to preprocess your data into that projection and QGIS is a great tool for that but there are many others such as gdal.

Related

Creating a Rule in NOAA/CDR/AVHRR/NDVI/V5 TO Only display ndvi for dense vegetation google earth engine

I'm trying to apply a rule to NOOA NDVI the already classified region to only display dense vegetation areas but it's saying ndvi is not a function, any help will be much appreciated.
Here is the code:
//collecting data using ndvi
var good = ee.ImageCollection('NOAA/CDR/AVHRR/NDVI/V5')
.filter(ee.Filter.date('2018-05-01', '2018-06-01'))
//.median()
//.good.lt(0.27).and(good.gt(0.18))
//.map(function(good){return good.lt(0.18).and(good.gt(0.27))})
.map(function(good){return good.clip(roi)});
Map.setCenter (37.577717495842506,0.3597340638009545,12);
var ndvi = good.select('NDVI')
var ndvi2 =ndvi
.where(ndvi.gt(0.27).and(ndvi.lte(0.36)), 4)
.where(ndvi.gt(0.36).and(ndvi.lte(0.74)), 5)
var ndvi2 = ndvi2.clip(roi);
The error shows this
Line 14: ndvi.gt is not a function
I would need to see more of your script to give you a full answer, but from what you have provided, it appears that ndvi is an ee.ImageCollection() and the .gt() and .lte() functions only work on ee.Image(). You will need to create a function that maps your intended rule over each image in the image collection to get what you want.

harp.gl: properly scaling georeferenced 3D geometries (in metres) added through three.js

I have a 3D model in a coordinate system that is defined in metres. The coordinates have been transformed to have the centre of the bounding box of the model as the origin. A vertex with the coordinates (1, 0, 0) would thus lie 1 metre from the origin.
When trying to add the geometries to the map, with the actual latitude/longitude of the origin as geoPosition, they don't get placed at the exact location and appear smaller than they are. How could I solve this?
Thanks.
You can center the map at whatever point you would like in the world with this method:
map.setCameraGeolocationAndZoom(
//Singapore coordinates and zoom level 16:
new harp.GeoCoordinates(1.278676, 103.850216), 16
);
You can specify the projection type in the MapView's constructor.
To implement a globe projection:
const map = new harp.MapView({
canvas,
theme: "https://unpkg.com/#here/harp-map-theme#latest/resources/berlin_tilezen_base_globe.json",
projection: harp.sphereProjection,
//For tile cache optimization:
maxVisibleDataSourceTiles: 40,
tileCacheSize: 100
});
//And set it to a view where you can see the whole world:
map.setCameraGeolocationAndZoom(new harp.GeoCoordinates(1.278676, 103.850216), 4);
Please refer documentation for more reference:
https://developer.here.com/tutorials/harpgl/#modify-the-map

How to make ee.Reducer.mean() give me a float instead of a binary number?

I'd like to reduce the resolution for a binary layer of the max extent of water, and I'd like the resulting layer to represent percent of water pixels. However when I use ee.Reducer.mean() as seen below, the resulting layer is only has binary values still. How can I get a float instead?
//The image in question
var water = ee.Image('JRC/GSW1_1/GlobalSurfaceWater').clip(roi);
//Current code
var watermodis = water.select(['max_extent'])
.reproject({
crs:modisproj
}).reduceResolution({
reducer:ee.Reducer.mean(),
});
Turns out I just had the order of the reproject and the reduceResolution wrong, should be
var watermodis = water.select(['max_extent'])
.reduceResolution({
reducer:ee.Reducer.mean(),
maxPixels:1310
}).reproject({
crs:modisproj
});

How to get X Y Z coordinates of tile by click on Leaflet map

I want to ask for help to deal with the possible use of non-standard coordinates on the map Leaflet.
I want to use Leaflet to display custom maps with my own tile generator. Tiles are generated on the fly by script, depending on where it is planned to display (parameters {x}, {y}, {z} in the URL request to the script)
Map will be zoomable (from 0 to 10), size of ~16000 * 16000 tiles in maximum zoom, and 16 * 16 tiles in a minimum) and it will display a variety of objects, each object in a separate tile.
Each tile of 64 * 64 pixels is the object on map.
For each object (a square-tile) I want to display it`s information on mouse click, by sending via AJAX request to the server. I did not want to pre-load all information about all objects for the goal of optimization.
My main issue - I cannot understand how to correctly get the X Y Я coordinates of the tile on which mouse clicked.
Essentially because each tile when it is loaded from the server is bound to the grid {x}, {y}, {z}, and so I want to get these {x}, {y}, {z} from clicks on the map and send them for further AJAX request for getting information about the object.
Now it is possible to get click point as Latlng coordinates or coordinates in pixels relative to the upper-left corner of the map, which I cannot reference to tiles grid.
And also I wanted to know the possibility to get the coordinates of the click relative to the tile. For example, If the tile has dimensions of 64 * 64, and click was in the center of the tile, so how can I get relative coordinate of click [32, 32]?
Because If we knowing {X}, {Y}, {Z} coordinates of the tile and relative X* and Y* coordinates of click inside the tile, then we can do “universal alternative coordinate grid”.
May be this is not a problem and it can be solved easily, but I've never worked with any Maps API, and therefore I want to know the answer to this question.
Thanks in advance for your help!
Here is a working example for getting Zoom, X, and Y coordinates of clicked tile (using openstreet map): http://jsfiddle.net/84P9r/
function getTileURL(lat, lon, zoom) {
let xtile = parseInt(Math.floor((lon + 180) / 360 * (1 << zoom)));
let ytile = parseInt(Math.floor((1 - Math.log(Math.tan(lat.toRad()) + 1 / Math.cos(lat.toRad())) / Math.PI) / 2 * (1 << zoom)));
return zoom + "/" + xtile + "/" + ytile;
}
based on an answer https://stackoverflow.com/a/19197572
You can use the mouseEventToLayerPoint and mouseEventToContainerPoint methods in the Leaflet API to convert pixels onscreen to pixels relative to the top-left of the map, and then using a little math, you can derive the location within a tile.
This is what Leaflet does internally:
const tileSize = [256, 256]
let pixelPoint = map.project(e.latlng, map.getZoom()).floor()
let coords = pixelPoint.unscaleBy(tileSize).floor()
coords.z = map.getZoom() // { x: 212, y: 387, z: 10 }

Check if a point is inside a Polygon with the Google Maps API

I am developing an application using the Google Maps API v3, and I'm struggling to know how to find out if an X coordinate is inside a polygon.
You can use the Geometry Library of the Google Maps JS API. There's a function called containsLocation which tells you if a given LatLng is inside a Polygon. Note that it's a Polygon, not a Polyline. A Polyline is (as it says in the name) a line. So there is no such thing as a point being inside a polyline. You can check if a point is inside a Polygon with the containsLocation function.
google.maps.geometry.poly.containsLocation(somePoint, somePolygon)
In iOS it can be done by using GMSGeometryContainsLocation
Just create a GMSMutablePath, then fill with vertexes of your polygon and test the point.
Example(Swift 4.0):
func isWithin(_ point: CLLocationCoordinate2D) -> Bool {
let p = GMSMutablePath()
p.add(CLLocationCoordinate2D(latitude:30.02356126, longitude: -90.07047824))
p.add(CLLocationCoordinate2D(latitude:30.02501037, longitude: -90.0614231))
p.add(CLLocationCoordinate2D(latitude:30.03321034, longitude: -90.0617981))
p.add(CLLocationCoordinate2D(latitude:30.03192855, longitude: -90.07342815))
return GMSGeometryContainsLocation(point, p, true)
}
Note: If the last param of GMSGeometryContainsLocation is set to true, the GMSMutablePath is composed of great circle segments, otherwise it's of rhumb (loxodromic) segments.

Resources