Projecting an Image on Google Map using OpenLayers 3 - google-maps

I am trying to overlay a satellite image (a 6471x7669 jpg file) over Google Map using OL3. The image file's meta-data and projection info is provided as:
Driver: JP2ECW/ERDAS JPEG2000 (SDK 3.x)
Files: /mnt/NAIP/TN/2012/34084/m_3408403_ne_16_1_20120527_20120911.jp2
Size is 6471, 7669
Coordinate System is:
PROJCS["NAD83 / UTM zone 16N",
GEOGCS["NAD83",
DATUM["North_American_Datum_1983",
SPHEROID["GRS 1980",6378137,298.2572221010002,
AUTHORITY["EPSG","7019"]],
AUTHORITY["EPSG","6269"]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4269"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",-87],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AUTHORITY["EPSG","26916"]]
Origin = (710739.000000000000000,3875921.000000000000000)
Pixel Size = (1.000000000000000,-1.000000000000000)
Metadata:
COLORSPACE=MULTIBAND
COMPRESSION_RATE_TARGET=9
VERSION=1
Corner Coordinates:
Upper Left ( 710739.000, 3875921.000) ( 84d41'26.44"W, 35d 0'14.31"N)
Lower Left ( 710739.000, 3868252.000) ( 84d41'33.42"W, 34d56' 5.56"N)
Upper Right ( 717210.000, 3875921.000) ( 84d37'11.35"W, 35d 0' 9.39"N)
Lower Right ( 717210.000, 3868252.000) ( 84d37'18.55"W, 34d56' 0.64"N)
Center ( 713974.500, 3872086.500) ( 84d39'22.44"W, 34d58' 7.49"N)
Band 1 Block=256x256 Type=Byte, ColorInterp=Undefined
Description = Band #1
Overviews: 3235x3834, 1617x1917, 808x958, 404x479, 202x239
Band 2 Block=256x256 Type=Byte, ColorInterp=Undefined
Description = Band #2
Overviews: 3235x3834, 1617x1917, 808x958, 404x479, 202x239
Band 3 Block=256x256 Type=Byte, ColorInterp=Undefined
Description = Band #3
Overviews: 3235x3834, 1617x1917, 808x958, 404x479, 202x239
Band 4 Block=256x256 Type=Byte, ColorInterp=Undefined
Description = Band #4
Overviews: 3235x3834, 1617x1917, 808x958, 404x479, 202x239
The problem I'm having is to interpret the data and figure out what projection to use (I'm not a geographer). I have already tested both EPSG:900913 and EPSG:3857 to transform to EPSG:4326, but it doesn't seem to work:
var lonlat = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
The provided data mentions EPSG:7019, EPSG:6269, EPSG:4269, EPSG:9001, and EPSG:26916, none of which seem to have Proj4js definitions. The provided corner & center lat/lons coordinates are pretty accurate.
My questions are: is there an existing proj4.defs for this? If not, how can I create one? Any help on this is greatly appreciated.
UPDATE
Expanding on this question further: Initially we center the static image over Google Map just fine.
But not sure what transformation to use as the layers are moved together. In a nutshell what should be the transformation <transform> in this code?
view.on('change:center', function() {
var center = ol.proj.transform(view.getCenter(), <transform>, 'EPSG:4326');
gmap.setCenter(new google.maps.LatLng(center[1], center[0]))
});

You source image is in NAD83 UTM 16N or EPSG:26916 see http://spatialreference.org/ref/epsg/nad83-utm-zone-16n/
UTM is a Transverse Mercator projection with vertical 6 degree strips of the world projected onto a cylinder with its axis through the poles. Google maps uses a spherical Mercator (horizontal cylindrical) projection - EPSG:3857. The properties of these two are quite different - you will not be able to accurately overlay your 26916 image on a 3857 map without reprojecting it.
Have you looked at this http://openlayers.org/en/latest/examples/reprojection-image.html ?
Alternatively, you could use a GIS program of some sort to re-project your image to 3857 for easier composition with a 3857 map - say something like GlobalMapper.

Related

How to calculate SAVI with MODIS in Google Earth Engine (Getting Error: Image.select: Pattern 'B2' did not match any bands.)

I am trying to calculate SAVI vegetation index using MODIS data. But I am getting an error showing:
Image.select: Pattern 'B2' did not match any bands.
Code:
countries = ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017")
canada = countries.filter(ee.Filter.eq("country_na", "Canada"))
image = ee.ImageCollection("MODIS/061/MOD09A1")\
.filterDate('2017-01-01','2017-12-31')\
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',10))\
.filterBounds(canada)\
.median()\
.clip(canada)
savi = image.expression(
'1.5*((NIR-RED)/(NIR+RED+0.5))',{
'NIR':image.select('B2'),
'RED':image.select('B1')
}).rename('savi')
saviVis = {'min':0.0, 'max':1, 'palette':['yellow', 'green']}
Map = geemap.Map()
Map.addLayer(savi, saviVis, 'SAVI')
Map
Why am I getting this error? Isn't B1 designated to Red and B2 to NIR?
The general thing to do when you hit this type of problem is to start examining the dataset for what is actually there — how many images are you matching, what properties and bands those images have, etc. I found two problems:
Your filter criteria matched zero images. Therefore the collection is empty, and therefore the median() image from that collection has no bands at all. (You can check this by putting the collection in a variable and printing the size() of it.) You will need to adjust the criteria.
It seems that the main reason they didn't match is that the images in MODIS/061/MOD09A1 do not have a CLOUDY_PIXEL_PERCENTAGE property.
The band names for MODIS/061/MOD09A1 are not B1, B2, ... but sur_refl_b01, sur_refl_b02 and so on. You can see this with the Inspector in the Earth Engine Code Editor, or on the dataset description page.
Perhaps you were working from information about a different dataset?
With the two problems above fixed, your code produces some results. This is the (JS) version I produced while testing (Code Editor link):
var countries = ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017");
var canada = countries.filter(ee.Filter.eq("country_na", "Canada"));
var images = ee.ImageCollection("MODIS/061/MOD09A1")
.filterDate('2017-01-01','2017-12-31')
// .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',10))
.filterBounds(canada);
// print(images);
var image = images.median().clip(canada);
Map.addLayer(canada);
Map.addLayer(image);
var savi = image.expression(
'1.5*((NIR-RED)/(NIR+RED+0.5))',{
'NIR':image.select('sur_refl_b02'),
'RED':image.select('sur_refl_b01')
}).rename('savi');
var saviVis = {'min':0.0, 'max':1, 'palette':['yellow', 'green']};
Map.addLayer(savi, saviVis, 'SAVI')

ITK Filter Error: "Inputs do not occupy the same physical space" after affine registration

I'm attempting to perform diffeomorphic demon registration of two MRI images. The processing pipeline has been this so far:
Skull-stripping
Anisotropic Diffusion (smoothing)
Histogram Matching
Affine registration
Diffeomorphic Demons Registration
I didn't come up with the process, just fixing and cleaning up a Slicer software tool several researchers have built. I'm a summer student and quite unfamiliar with domain, however I've started to more less understand what's going on. The problem I've been unable to solve for the past several weeks is this error:
itk::ExceptionObject (0x1231130)
Location: "void itk::ImageToImageFilter<TInputImage, TOutputImage>::VerifyInputInformation() [with TInputImage = itk::Image<itk::Vector<float, 3u>, 3u>; TOutputImage = itk::Image<itk::Vector<float, 3u>, 3u>]"
File: /home/parallels/Desktop/Slicer-SuperBuild/ITKv4/Modules/Core/Common/include/itkImageToImageFilter.hxx
Line: 241
Description: itk::ERROR: DiffeomorphicDemonsRegistrationFilter(0x13870b0): Inputs do not occupy the same physical space!
InputImage Origin: [7.9639916e+01, -1.1042095e+02, -1.0426932e+02], InputImageMovingImage Origin: [-8.8678563e+01, -1.4923204e+02, 1.2193930e+02]
Tolerance: 1.5000000e-05
InputImage Spacing: [1.5000000e+01, 1.5000000e+01, 1.9199951e+01], InputImageMovingImage Spacing: [1.5154560e+01, 1.5108180e+01, 1.9319538e+01]
Tolerance: 1.5000000e-05
InputImage Direction: 1.5926319e-08 1.4070701e-08 -1.0000000e+00
9.9237583e-01 -1.2324859e-01 1.4070700e-08
1.2324859e-01 9.9237583e-01 1.5926320e-08
, InputImageMovingImage Direction: -0.0000000e+00 5.5205551e-10 1.0000000e+00
5.5205551e-10 1.0000000e+00 -5.5205553e-10
-1.0000000e+00 5.5205551e-10 0.0000000e+00
Tolerance: 1.0000000e-06
From what I understand, the diffeomorphic registration relies on the two images being coincident, hence the affine registration step beforehand. For some reason though, the affine transformation doesn't line up the two images properly. As a result, they don't occupy the same physical space. I'm clearly missing something but can't seem to figure out what it is.
The affine registration is performed with this file (I made some edits on my local copy to comply with the Slicer module's way of input/output but they're nearly identical). The transform that was created had the following characteristics:
Optimizer stop condition: RegularStepGradientDescentOptimizerv4: Step too small after 33 iterations. Current step (9.76563e-05) is less than minimum step (0.0001).
Result =
Center X = -1.95155
Center Y = 11.6381
Center Z = 36.5165
Translation X = 1.09423
Translation Y = 0.021133
Translation Z = -0.0154539
Iterations = 34
Metric value = 8974.52
Scale 1 = 1.15384
Scale 2 = 1.08962
Angle (degrees) = -5.6116
The following code was used to save the transform to a file:
// Write the transform to a file
itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
transformWriter->SetInput( registration->GetOutput()->Get() );
transformWriter->SetFileName( outputMatrix.c_str() );
transformWriter->Update();
And the demon registration is performed with this file (Made a few edits but mostly the same as well). The affine transform is loaded at line 799.
Reading transform from transform input file.
Found: AffineTransform (0x1e0c0b0)
RTTI typeinfo: itk::AffineTransform<double, 3u>
Reference Count: 3
Modified Time: 1322
Debug: Off
Object Name:
Observers:
none
Matrix:
1.01338 0.0887047 0.0223631
-0.11891 1.09423 0.021133
-0.0154539 0.0302253 1.14062
Offset: [-0.256888, -34.7809, -17.895]
Center: [-1.95155, 11.6381, 36.5165]
Translation: [1.56597, -32.6804, -12.3781]
Inverse:
0.977286 -0.0787352 -0.0177019
0.105999 0.905809 -0.0188607
0.0104321 -0.0250698 0.876975
Singular: 0
Edit: Commenting out the following line does not change anything in the resulting output. ie the initial displacement is not being applied at all. Still don't know why.
typedef typename itk::MultiResolutionPDEDeformableRegistration <ImageType, ImageType, DeformationFieldType, PixelType > MultiResRegistrationFilterType;
typename MultiResRegistrationFilterType::Pointer multires = MultiResRegistrationFilterType::New();
// Commenting out this line doesn't change anything
multires->SetArbitraryInitialDisplacementField ( inputDefField );
It looks like the Diffeomorphic Demons Registration code you are using requires that Fixed and Moving images have the same physical space, meaning:
Origin
Spacing
Dimensions
Did you try to resample your moving image to the fixed image space, and then call the Diffeomorphic Demons Registration with this resampled moving image and fixed image?
I didn't know this EZminc code but it looks like it requires both inputs to be in the same space somehow.

Mapbox - What are my layer ID's?

I'm new to using Mapbox.
I'm trying to add a new layer to my map that is above the water layer but below labels.
map.addLayer({
'id': 'maine',
'type': 'fill',
'source': 'maine',
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8
}
}, 'water');
(This code was taken from some example code from Mapbox.)
Right now, this creates a layer that is below the water layer and the labels. However, I can't figure out what layer ID would bring it above the water layer.
This is the stylesheet I'm using:
mapbox://styles/mapbox/light-v9
How do I find the other valid layer ID's for this style sheet? I've tried 'streets', 'roads', 'road', 'land', etc, but nothing has worked. I thought this link included all the layer names:
https://www.mapbox.com/studio/styles/mapbox/light-v9/
but the only one that keeps my new layer from just being on top of everything is 'water'. Help!
You can retrieve style specifications from the styles api.
For example to get all the layer_ids on the light-v10 style you could do this in python:
import requests
for layer in requests.get('https://api.mapbox.com/styles/v1/mapbox/light-v10?access_token=pk.eyJ1IjoiYmNrb2hhbiIsImEiOiJja2Zvamc4ejcyZjRxMzFwMXNwcGIxdDVlIn0.KdUOuJFIaV4eCzq94AgMGw').json()['layers']: print(layer['id'])
Which yields:
land
landcover
national-park
landuse
water-shadow
waterway
water
hillshade
land-structure-polygon
land-structure-line
aeroway-polygon
aeroway-line
building-outline
building
tunnel-street-minor-low
tunnel-street-minor-case
tunnel-primary-secondary-tertiary-case
tunnel-major-link-case
tunnel-motorway-trunk-case
tunnel-construction
tunnel-path
tunnel-steps
tunnel-major-link
tunnel-pedestrian
tunnel-street-minor
tunnel-primary-secondary-tertiary
tunnel-motorway-trunk
road-pedestrian-case
road-minor-low
road-street-low
road-minor-case
road-street-case
road-secondary-tertiary-case
road-primary-case
road-major-link-case
road-motorway-trunk-case
road-construction
road-path
road-steps
road-major-link
road-pedestrian
road-minor
road-street
road-secondary-tertiary
road-primary
road-motorway-trunk
road-rail
bridge-pedestrian-case
bridge-street-minor-low
bridge-street-minor-case
bridge-primary-secondary-tertiary-case
bridge-major-link-case
bridge-motorway-trunk-case
bridge-construction
bridge-path
bridge-steps
bridge-major-link
bridge-pedestrian
bridge-street-minor
bridge-primary-secondary-tertiary
bridge-motorway-trunk
bridge-rail
bridge-major-link-2-case
bridge-motorway-trunk-2-case
bridge-major-link-2
bridge-motorway-trunk-2
admin-1-boundary-bg
admin-0-boundary-bg
admin-1-boundary
admin-0-boundary
admin-0-boundary-disputed
road-label
waterway-label
natural-line-label
natural-point-label
water-line-label
water-point-label
poi-label
airport-label
settlement-subdivision-label
settlement-label
state-label
country-label
I would just add a note of caution that the layer ids for the default styles can change significantly version to version.
You can experiment in Mapbox.com/studio by adding your maine tile set into a new style, then you can move the layer interactively to experiment and proof the effect that you want.
The second parameter for addLayer is before, so your maine source should've gone before the water layer. See the docs on addLayer for details
https://www.mapbox.com/mapbox-gl-js/api/#Map#addLayer
The names of the layers are identified by "id" in the Style.json.
You can find the names of the layers by going to the link you posted
https://www.mapbox.com/studio/styles/mapbox/light-v9/
there you will see a nice visualization of the layer ids from Mapbox.
The water layer is near the bottom of the layers stack of the Mapbox light style.
Here are the layers with water in the "id.
"id": "waterway-river-canal",
"id": "water shadow",
"id": "water",
"id": "waterway-label",
"id": "water-label",
Your layer ID can be found by opening your map in Mapbox Studio. If you go to View style details (the box with an arrow in the top right corner of the left hand window, it will reveal all the layers.

Google Map API Marker Icon Url?

I'm trying to change marker icon to "red-circle" or "red-pin" or anything else.
In these codes;
markerOptions: {
icon: 'images/beachflag.png'
},
the marker doesn't show. But if i make the icon line a comment line, so marker shows like "red-pin" icon
So, i need to marker icons list or URL list which directly supported by Google Map API. Or is there such a thing?
Thank you.
This is the (unofficial) list that I refer to:
https://groups.google.com/d/msg/Google-Maps-API/2k3T5hwI5Ck/RRso0D2jB1oJ
provided by pamela (who was a Google employee at the time), it is fairly old, but still accurate.
=================== -- ============================
-- from Mike Williams --
It's also worth noting that only the original set of icons is available
in the location that was mentioned earlier in this thread
E.g. blue.png is available at both locations
http://maps.google.com/mapfiles/ms/icons/blue.png
http://maps.google.com/mapfiles/ms/micons/blue.png
But the new yen.png icon is only here
http://maps.google.com/mapfiles/ms/micons/yen.png
-- from pamela --
I'll provide the list to you here, but you should know it's possible
some of these icons will disappear later. You may want to copy to your
own server to be sure.
Happy reading... :)
POI.png
POI.shadow.png
arts.png
arts.shadow.png
bar.png
bar.shadow.png
blue-dot.png
blue-pushpin.png
blue.png
bus.png
bus.shadow.png
cabs.png
cabs.shadow.png
camera.png
camera.shadow.png
campfire.png
campfire.shadow.png
campground.png
campground.shadow.png
caution.png
caution.shadow.png
coffeehouse.png
coffeehouse.shadow.png
convienancestore.png
convienancestore.shadow.png
cycling.png
cycling.shadow.png
dollar.png
dollar.shadow.png
drinking_water.png
drinking_water.shadow.png
earthquake.png
earthquake.shadow.png
electronics.png
electronics.shadow.png
euro.png
euro.shadow.png
fallingrocks.png
fallingrocks.shadow.png
ferry.png
ferry.shadow.png
firedept.png
firedept.shadow.png
fishing.png
fishing.shadow.png
flag.png
flag.shadow.png
gas.png
gas.shadow.png
golfer.png
golfer.shadow.png
green-dot.png
green.png
grn-pushpin.png
grocerystore.png
grocerystore.shadow.png
groecerystore.png
groecerystore.shadow.png
helicopter.png
helicopter.shadow.png
hiker.png
hiker.shadow.png
homegardenbusiness.png
homegardenbusiness.shadow.png
horsebackriding.png
horsebackriding.shadow.png
hospitals.png
hospitals.shadow.png
hotsprings.png
hotsprings.shadow.png
info.png
info.shadow.png
info_circle.png
info_circle.shadow.png
landmarks-jp.png
landmarks-jp.shadow.png
lightblue.png
lodging.png
lodging.shadow.png
ltblu-pushpin.png
ltblue-dot.png
man.png
man.shadow.png
marina.png
marina.shadow.png
mechanic.png
mechanic.shadow.png
motorcycling.png
motorcycling.shadow.png
movies.png
movies.shadow.png
msmarker.shadow.png
orange-dot.png
orange.png
parkinglot.png
parkinglot.shadow.png
partly_cloudy.png
partly_cloudy.shadow.png
pharmacy-us.png
pharmacy-us.shadow.png
phone.png
phone.shadow.png
picnic.png
picnic.shadow.png
pink-dot.png
pink-pushpin.png
pink.png
plane.png
plane.shadow.png
police.png
police.shadow.png
postoffice-jp.png
postoffice-jp.shadow.png
postoffice-us.png
postoffice-us.shadow.png
purple-dot.png
purple-pushpin.png
purple.png
pushpin_shadow.png
question.png
question.shadow.png
rail.png
rail.shadow.png
rainy.png
rainy.shadow.png
rangerstation.png
rangerstation.shadow.png
realestate.png
realestate.shadow.png
recycle.png
recycle.shadow.png
red-dot.png
red-pushpin.png
red.png
restaurant.png
restaurant.shadow.png
sailing.png
sailing.shadow.png
salon.png
salon.shadow.png
shopping.png
shopping.shadow.png
ski.png
ski.shadow.png
snack_bar.png
snack_bar.shadow.png
snowflake_simple.png
snowflake_simple.shadow.png
sportvenue.png
sportvenue.shadow.png
subway.png
subway.shadow.png
sunny.png
sunny.shadow.png
swimming.png
swimming.shadow.png
toilets.png
toilets.shadow.png
trail.png
trail.shadow.png
tram.png
tram.shadow.png
tree.png
tree.shadow.png
truck.png
truck.shadow.png
volcano.png
volcano.shadow.png
water.png
water.shadow.png
waterfalls.png
waterfalls.shadow.png
webcam.png
webcam.shadow.png
wheel_chair_accessible.png
wheel_chair_accessible.shadow.png
woman.png
woman.shadow.png
yellow-dot.png
yellow.png
yen.png
yen.shadow.png
ylw-pushpin.png

MySQL query to extract multiple Lat/Long coordinates and plot on Google map

I have the following MySQL query below. I'm trying to pull out the four sets of coordinates, then plot them on my custom Google v3 API page. (I also need it to "connect" the dots with blue lines as well)
Here is what the original "printable_text" column data looks like:
Grids : T04SR08W09NW
BestFit: 38.204326/-89.995942 38.204330/-89.993452
: 38.203490/-89.993451 38.203486/-89.995941
PreMark: NO Directional Boring: NO Depth>7Ft: NO
Here is my current MySQL query:
SELECT ticket
, SUBSTR(printable_text
, LOCATE('BestFit: ',printable_text)+9
, LOCATE('PreMark:', printable_text) - LOCATE('BestFit: '
, printable_text) - 9) AS coord
, REPLACE((SUBSTR(printable_text
, LOCATE('BestFit: ',printable_text)+9
, LOCATE('PreMark:', printable_text) - LOCATE('BestFit: '
, printable_text) - 9)),'/',',') AS coord
FROM tickets
WHERE ticket = 'A3041073'
Here is what I have extracted so far:
38.204326/-89.995942 38.204330/-89.993452 : 38.203490/-89.993451 38.203486/-89.995941
38.204326,-89.995942 38.204330,-89.993452 : 38.203490,-89.993451 38.203486,-89.995941
I'm guessing I need to get rid of the "/", "spaces", "colons", and feed the four coordinates to my Google API for plotting and connecting..?