Proj4: How to convert coordinates from EPSG 4326 to EPSG 31370 - javascript

Need to convert coordinates of Leaflet.js Map from EPSG 4326 to EPSG 31370.
What I did till now: Defining EPSG 31370
proj4.defs["EPSG:31370"] = "+proj=lcc +lat_1=51.16666723333333 +lat_2=49.8333339 +lat_0=90 +lon_0=4.367486666666666 +x_0=150000.013 +y_0=5400088.438 +ellps=intl +towgs84=-106.8686,52.2978,-103.7239,0.3366,-0.457,1.8422,-1.2747 +units=m +no_defs";
And Calling it:
console.log(proj4('EPSG:31370', [map.getCenter().lat,map.getCenter().lng]));
However, it results into '31370 undefined' error in console.

The problem is with your initial definitions for EPSG 31370. The following works.
// Define the source and target projections
proj4.defs("EPSG:4326", "+proj=longlat +datum=WGS84 +no_defs");
proj4.defs("EPSG:31370", "+proj=lcc +lat_1=51.16666723333333 +lat_2=49.8333339 +lat_0=90 +lon_0=4.367486666666666 +x_0=150000.013 +y_0=5400088.438 +ellps=intl +towgs84=-106.8686,52.2978,-103.7239,0.3366,-0.457,1.8422,-1.2747 +units=m +no_defs");
// Define the coordinates to convert
const sourceCoord = [1, 1];
// Convert the coordinates
const targetCoord = proj4("EPSG:4326", "EPSG:31370", sourceCoord);
console.log(targetCoord);
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.8.1/proj4.min.js" integrity="sha512-JToqu2hzfiepDTg9LjkVzYhUhTcYGJIj2aGOn3Q+7sPVSi2n+vmpxISCbOJ2b3I4OQmqG0KQYovX6f3Rx+etAQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
After getting these conversion results, you can verify them here.

Related

Using proj4 and EPSG code to transform into different coordinate system

I have coordinates in EPSG:25833, which is UTM, zone 32N.
I want to transform them into EPSG:3857, WebMercator. The documentation says
var firstProjection = 'PROJCS["NAD83 / Massachusetts Mainland",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",42.68333333333333],PARAMETER["standard_parallel_2",41.71666666666667],PARAMETER["latitude_of_origin",41],PARAMETER["central_meridian",-71.5],PARAMETER["false_easting",200000],PARAMETER["false_northing",750000],AUTHORITY["EPSG","26986"],AXIS["X",EAST],AXIS["Y",NORTH]]';
var secondProjection = "+proj=gnom +lat_0=90 +lon_0=0 +x_0=6300000 +y_0=6300000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
proj4(firstProjection,secondProjection,[2,5]);
Is it possible to pass only a EPSG string as firstProjection and secondProjection? Passing i.e. for EPSG:25833 which is UTM 32N contains already all the needed information. Why is there a need to pass to do this
Proj4js.defs["EPSG:25833"] = "+proj=utm +zone=33 +ellps=GRS80 +units=m +no_defs";
Using this definition restricts me too. What if EPSG:25833 changes to another EPSG? Then I have to update this +proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs too...
Proj4js is distributed with the following coordinate systems,
export default function(defs) {
defs('EPSG:4326', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees");
defs('EPSG:4269', "+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees");
defs('EPSG:3857', "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=#null +no_defs");
defs.WGS84 = defs['EPSG:4326'];
defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857
defs.GOOGLE = defs['EPSG:3857'];
defs['EPSG:900913'] = defs['EPSG:3857'];
defs['EPSG:102113'] = defs['EPSG:3857'];
}
https://github.com/proj4js/proj4js/blob/master/lib/global.js
All the other coordinate systems need to be defined by the user. Compare with PROJ4 C library that is distributed with a EPSG database,...
and that is the reason you can't pass just a EPSG code, unless it's defined elsewhere.
Just a note,
You can declare, for example,
Proj4js.defs["ETRS89 UTM32"] = "+proj=utm +zone=33 +ellps=GRS80 +units=m +no_defs";
instead of
Proj4js.defs["EPSG:25833"] = "+proj=utm +zone=33 +ellps=GRS80 +units=m +no_defs";
And, then, an alias
Proj4js.MYEPSG = Proj4js.defs["EPSG:25833"]

Convert Long And Lat to X Y coordinate using ArcGis Api For Javascript

Hello i'm trying to convert long,lat values to X,Y using ArcGis Api For Javascript
var i = esri.geometry.lngLatToXY(3.13, 36.742)
console.log(i); //returns Array [ 348541.32567373366, 4403205.668961807 ]
in what system does this conversion take place?
is there a method to specify the projection system?
note: the conversion is done from decimal degree to meters
i followed this :
https://developers.arcgis.com/javascript/3/jsapi/esri.geometry.webmercatorutils-amd.html
This method is used to convert geographic coordinate system longitude/latitude (wkid 4326) to projected coordinate system Web Mercator (wkid 102100).
Default esri map use Web Mercator as projection system. If you need to convert your coordinates to an other coordinate system you need to use the project method of GeometryService :
https://developers.arcgis.com/javascript/3/jsapi/geometryservice-amd.html
Example:
require(["esri/geometry/Point", "esri/tasks/GeometryService", "esri/tasks/ProjectParameters", "esri/SpatialReference", "dojo/domReady!"],
function(Point, GeometryService, ProjectParameters, SpatialReference) {
var outSR = "YOUR_OUTPUT_COORDINATE_SYSTEM"; // `wkid {number}`
var geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
var inputpoint = new Point({
longitude: "YOUR_LONGITUDE_INPUT",
latitude: "YOUR_LATITUDE_INPUT"
});
var projectParams = new ProjectParameters();
projectParams.geometries = [inputpoint];
projectParams.outSR = new SpatialReference({ wkid: outSR });
geometryService.project(projectParams, (result) => {
let outputpoint = result[0]; // outputpoint first element of result array
console.log("Result x:", outputpoint.x, "y :", outputpoint.y);
});
});
Wkid numbers can be found here:
projected coordinate system: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Projected_coordinate_systems/02r3000000vt000000/
Geographic coordinate system: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Geographic_coordinate_systems/02r300000105000000/
EDIT
Here is a working example: Plunker

OpenLayers 2: Unexpected results from Point.distanceTo()

I try to use OpenLayers 2 to calculate the distance between Points of a GPS track. I tried using Point.distanceTo(), with just the points, and with the points transformed to my map. In both cases I get a result I can't really interpret:
var epsg4326 = new OpenLayers.Projection("EPSG:4326");
var pointA = new OpenLayers.Geometry.Point(5.339911, 60.371876);
var pointB= new OpenLayers.Geometry.Point(5.34003, 60.371471);
console.log("raw: " + pointA.distanceTo(pointB));
pointA = new OpenLayers.Geometry.Point(5.339911, 60.371876).transform(epsg4326, this.map.getProjectionObject());
pointB= new OpenLayers.Geometry.Point(5.34003, 60.371471).transform(epsg4326, this.map.getProjectionObject());
console.log("transformed: " + PointA.distanceTo(pointB));
gives the following output:
raw: 0.0004221208357810271
transformed: 92.1524487013366
According to http://www.movable-type.co.uk/scripts/latlong.html the result should be 45.51 m, which is consistent with my expectations.
Am I doing something wrong, or is the result in a unit I'm not expecting?
Try
var line = new OpenLayers.Geometry.LineString([pointA, pointB]);
console.log("Distance: " +line.getGeodesicLength(epsg4326));
this gives you 45,6 (Google Maps gives 46m)
-distanceTo wroks with planar measure (earth is not falt :D)
Calculate the closest distance between two geometries (on the x-y plane).
http://dev.openlayers.org/docs/files/OpenLayers/Geometry-js.html#OpenLayers.Geometry.distanceTo
Hope this helps

Polar to Cartesian coordinates function not outputting the correct data

I have a flight path with lat/long and elevation and I need to convert this to cartesin X,Y,Z for cesium.js.
I am running into the wall trying to convert this because I don't seem to be getting the right results from my function.
var R = 6371;
function polarToCartesian(latitude, longitude, elevation){
x = (R+elevation) * math.cos(latitude) * math.cos(longitude);
y = (R+elevation) * math.cos(latitude) * math.sin(longitude);
z = (R+elevation) * math.sin(latitude);
var ar = [x,y,z];
return ar;
}
I must not either have the correct formula for polar to cartesian or I don't have the correct radius of earth. I found somewhere that my radius should be 6371 but can't seem to find that same SO question for reference.
I am partialy checking if my code is correct by manually adding up the radius of the earth + altitude of the flight path at a given location and seeing if this equals the length of my x,y,z vector.
For example: x,y,z (3689.2472215653725,3183.2401988117012,13306.90338789763)
is outputted when I give my function this
-93.028,44.6942,7800
lat,long,elevation
Could someone point me to find the right js code to accomplish this conversion?
You should be using Cesium's built-in functions for this. See Cartesian3.fromDegrees and Cartesian3.fromDegreesArray.
For example:
var result = Cesium.Cartesian3.fromDegrees(latitude, longitude, elevation);
Note the result will be as Cesium expects: in meters, not kilometers. This also takes into account the shape of the Ellipsoid, for which the default is WGS84 (the Earth is not a perfect sphere, as your function presumes).
There is nothing wrong with the Yavascript per se. However, your equations are incorrect. You're looking to convert from Lat/Long/Alt to Spherical (aka Cartesian), which was answered here.
So you could rewrite above as:
function polarToCartesian(latitude, longitude, elevation){
const x = math.cos(latitude) * math.cos(longitude) * elevation;
const y = math.cos(latitude) * math.sin(longitude) * elevation;
const z = math.sin(latitude) * elevation;
return [x, y, z];
}

Create a map with coordinates-based marker using Javascript, jQuery and/or php

I am developing a client-server application and I need to create or obtain a geographical map with some markers (just red points, for example) on it based on lat and lang.
I have been looking on the web but I couldn't find anything ok for me.
I could do it using google maps but I think I can't use my own custom map-image and my custom markers.
However, this is an example of what I'd like to do more or less having some coordinates:
http://www.morrisda.com/?post=pointmap
Here explanation of how i managed this. With example !
Here source code:
function make_pointers(latitude, longitude) {
targetmap = document.getElementById("point_map");
//it's sure it will work when your map is a perfec square, so it's got height on the x and on the y for usefull debugging.
var asseX = $('#point_map').height()
var asseY = $('#point_map').height()
//lat and lang from imput
lang = longitude;
lat = latitude;
var source = new Proj4js.Proj('EPSG:4326'); //source coordinates will be in Longitude/Latitude, WGS84
var dest = new Proj4js.Proj('EPSG:3785'); //destination coordinates in meters, global spherical mercators projection, see http://spatialreference.org/ref/epsg/3785/
var mercator_object = new Proj4js.Point(lang,lat); //any object will do as long as it has 'x' and 'y' properties
Proj4js.transform(source, dest, mercator_object);
give_top = 19971868.8804*2 //this is how a meridian is long.
mercator_longitude = mercator_object.y //this is longitude by mercator
//this switch is if latitude is negative;
if (mercator_object.y > 0) {mercator_object.y = mercator_object.y + give_top/2}
if (mercator_object.y < 0 ) {mercator_object.y = give_top/2 + mercator_object.y}
//this is my lovely proportion, value of give_top is length of a meridian
mercator_distance = (asseY*mercator_longitude)/give_top;
//distance from 0:
y = asseY/2 - mercator_distance;
//proportion to make working on x;
//(180 + lang) makes lang from 0 to 360 instead of -180, +180.
//to understand, now image equator as a line, long 360.
//now we divide our coords (from 0 to 360) for 360, and the result is how far is this point from 0 on a 360-long line.
//now a simple proportion, and we get this distance on a line long like x axis, which is the width of our map.
// % is a Modulus (division remainder)
normalized_x_coords = (180 + lang)
x = (asseX * normalized_x_coords/ 360) % asseX;
//let's put this little points on my map (subtract -3 cause our point is large 6.)
console.log(x); //this is distance from left border;
console.log(y) //this is distance from bottom border
}
Remember you need jQuery and ProJ4js to use this. More info in previous link
Have a look at Slippy Map On Canvas project that is a implemenation of a slippy tiles map using HTML5. You can configure your own map and markers, and it also supports many other features which may be useful for you.

Categories