Open munirfarzeen opened 6 years ago
It's not directly supported.
You can use third party libraries to convert ecef xyz to wgs84 coordinate, such as ecef-projector
Then:
const projector = require('ecef-projector');
const [lat, lon, alt] = projector.unproject(x, y, z); //xyz is the ecef values
const layer = new maptalks.VectorLayer('v', { enableAltitude : true });
//6378137 is the radius of earth
new maptalks.Marker([lon, lat], { altitude : alt - 6378137 }).addTo(layer);
No, this is not what i wanted to do, maybe i was unclear. I have to make a map in ECEF coordinate system. Not just one point. any idea how to do that? do i have to make a CRF?
I think it's possible, but depends on what you want.
maptalks's coordinate system is also a cartesian XYZ system naturally fit for ECEF's need .
So you may use maptalks to present ECEF system like this:
const map = new maptalks.Map('map', {
center : [0, 0],
spatialReference : {
projection : 'identity', //identity means using cartesian system without any projection
'resolutions': (function () {
let res = Math.pow(2, 8);
const resolutions = [];
for (let i = 0; i < 18; i++) {
resolutions[i] = res;
res *= 0.5;
}
return resolutions;
})(),
'fullExtent': {
'top': 6378137,
'left': -6378137 ,
'bottom': -6378137 ,
'right': 6378137
}
}
});
const layer = new maptalks.VectorLayer('v', { enableAltitude : true }).addTo(map);
//x, y can be ECEF's [x, y] or [x, z] or [y, z]
//it depends on the main axes you choose for maptalks's ground plane
new maptalks.Marker([x, y], { altitude : z }).addTo(layer);
hi, thank you so much for the reply. but when i changed the code accordingly, i have no background image. should i add the baselayer from the openstreet ? oe should have own map?
i mean there is no map, just the empty page. URL from OPenstreet would work>?
Unfortunately, base map from openstreetmap can't be used in ECEF maps as it's a wgs84 REQUIRED map source. 😞
If you want to use ECEF data on openstreetmap maps, you have to convert ECEF data to wgs84 at first.
how do you suggest i do that? any idea?
i have one basic question, as far my understanding goes ECEF is cartesian XYZ system. and WGS84 is just a standard to define the shape of the earth? now when you say i have to convert ECEF data to wgs84, what exactly that mean? will the data still in XYZ. because the literature i studied says that openstreet maps uses WGS48 system but they have latitude and longitude. kindly point me right direction
Yeah, your understanding is right, WGS84 is a standard to define any position on the earth, it's an ellipsoid coordinate system that is totally different from cartesian XYZ.
Thus, to use osm basemap, you have to convert your ECEF data to wgs84 before adding to maps.
You can convert on your own with ecef-projector or sth else before creating maps.
Or, to make it easier for this conversion, you can create a customized projection object to convert ECEF data on the fly to wgs84 and then to mercator 3857(required by osm). This can let you input ecef data directly to maps. You can refer to this example of custom projection.
Replace proj4js in the example with ecef-projector like this:
const projector = require('ecef-projector');
const proj3857 = maptalks.projection.EPSG3857;
const projection = {
code : 'myecef',
project(ecef) : {
//as maptalk's coordinate only has [x,y], fix altitude to 6378137(the surface of earth)
const [lat, lon, alt] = projector.unproject(ecef.x, ecef.y, 6378137);
//convert wgs84 to 3857
return proj3857.project(new maptalks.Coordinate(lon, lat));
},
unproject(coord): {
//convert 3857 to wgs84
const lonlat = proj3857.unproject(coord);
const ecef = projector.project(lonlat.y, lonlat.x, 0);
return new maptalks.Coordinate(ecef[0], ecef[1]));
}
};
const map = new maptalks.Map('map', {
center: [-0.113049, 51.498568],
zoom: 13,
// spatial reference definition
spatialReference : {
projection : projection, // geo projection
resolutions : [ // map's zoom levels and resolutions
156543.03392804097,
78271.51696402048,
9135.75848201024,
19567.87924100512,
9783.93962050256,
4891.96981025128,
2445.98490512564,
1222.99245256282,
611.49622628141,
305.748113140705,
152.8740565703525,
76.43702828517625,
38.21851414258813,
19.109257071294063,
9.554628535647032,
4.777314267823516,
2.388657133911758,
1.194328566955879,
0.5971642834779395,
0.29858214173896974
],
fullExtent : { // map's full extent
'top': 6378137 * Math.PI,
'left': -6378137 * Math.PI,
'bottom': -6378137 * Math.PI,
'right': 6378137 * Math.PI
}
},
baseLayer : new maptalks.TileLayer('base',{
urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
subdomains: ['a','b','c','d'],
attribution: '© <a href="http://osm.org">OpenStreetMap</a> contributors, © <a href="https://carto.com/">CARTO</a>'
})
});
The above codes are not tested.
Actually i dont have ECEF data, i making application specific map, that is able to tell me my location in XYZ coordinates. I dont require latitude and longitude on my map. I just wanna know my location in XYZ does this makes sense? or is it possible?
So let me sum it up: you want to create a map with osm baselayer, and get locations on the map in XYZ coodinates? Am I right?
If I'm right, just create a map with customized projection mentioned above, you can get any XYZ location you need on the map.
yes, i want to use the titles from any public server and able to get the map in XYZ, and dimension would be in meters. Like if i travel one meter on map which should be equal to same one meter on earth so, if i follow those projections, i will be able to do that?
Yes, I think so.
You can have a try and return to me if you need any help any time.
okay, thank you so much for your time. I will try it.
hi again, i am new to javascript too. the line const projector = require('ecef-projector'); gives error uncaught reference error. it says require is a server side function not the client side. i tried including .js file in script, than i get the same error later in file. any way to solve it
Sorry mate, I only provide support for this library. 😞
Hi @fuzhenn ,
Thank you for this library. My question is related to this thread, maybe...
I am trying to load the basic example of the map and point the center to -33.856680307503595, 151.21530689724574
(approximately Sydney opera house) based on the coordinates I got from google maps.
somehow when the map is loaded its pointed somewhere else
const map = new maptalks.Map(mapName, {
center: [-33.856680307503595, 151.21530689724574],
zoom: 2,
baseLayer: new maptalks.GroupTileLayer('base-map', [
new maptalks.TileLayer('white-map', {
urlTemplate : 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
subdomains : ['a','b','c','d'],
attribution : '© <a href="http://www.osm.org/copyright">OSM</a> contributors, '+
'© <a href="https://carto.com/attributions">CARTO</a>'
})
])
})
I tried playing around spatialReference
option to change the projection to WGS84 but Im getting invalid projection error.
Do you have any idea what I might be missing?
@eLBirador The coordinates of the center point are reversed. In the maptalks system, the longitude and latitude in the coordinates are longitude before latitude after latitude.
so The correct code is
const map = new maptalks.Map(mapName, {
center: [-33.856680307503595, 151.21530689724574].reverse(),
zoom: 2,
baseLayer: new maptalks.GroupTileLayer('base-map', [
new maptalks.TileLayer('white-map', {
urlTemplate : 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
subdomains : ['a','b','c','d'],
attribution : '© <a href="http://www.osm.org/copyright">OSM</a> contributors, '+
'© <a href="https://carto.com/attributions">CARTO</a>'
})
])
})
maptalks's version and what browser you use?
master branch, google chrome
Issue description
https://dominoc925-pages.appspot.com/mapplets/cs_ecef.html I want to display map with ECEF xyz values as can be seen in the link. Is it possible with maptalk?
Please provide a reproduction URL (on any jsfiddle like site)
https://dominoc925-pages.appspot.com/mapplets/cs_ecef.html