Proj4js - 您可以在没有区域的情况下将纬度/经度转换为 UTM 吗?

问题描述 投票:0回答:3

我正在尝试使用 Proj4js 执行一些坐标转换,但关于如何使用它的信息很少。

我想要做的是将纬度和经度转换为 UTM 坐标,但我不知道该区域是什么。 这应该很容易,因为经度决定了区域,并且如果您知道默认情况下会出现该区域。

我尝试在 Proj4js 中执行此操作,但收到错误消息

“未捕获类型错误:未定义不是函数”

我的代码是这样的:

 proj4Arr = [-105.2098, 39.7458];
 var source = ('+proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees +no_defs');
 var dest = ("+proj=utm +ellps=GRS80 +datum=nad83 +units=m +no_defs");

 console.log(proj4(source, dest, proj4Arr));

我只是不知道是否可以在不包含该区域的情况下执行此操作。我可以先计算区域,然后根据需要将其放入字符串中,但我试图保持简单。

如果有人知道任何好的纯 js 资源示例(不一定使用 OpenLayers 3),我也将不胜感激。

谢谢!

javascript proj4js
3个回答
9
投票

今年是2021年,可以发布一个可运行的代码,它不仅可以回答问题,还可以演示导致坐标转换结果的所有步骤。

  function utmzone_from_lon(lon_deg) {
    //get utm-zone from longitude degrees
    return parseInt(((lon_deg+180)/6)%60)+1;
  }
  
  function proj4_setdef(lon_deg) {
    //get UTM projection definition from longitude
    const utm_zone = utmzone_from_lon(lon_deg);
    const zdef = `+proj=utm +zone=${utm_zone} +datum=WGS84 +units=m +no_defs`;
    return zdef;
  }
  
  // computation test
  let lon_input = 95.99;
  let lat_input = 15.15;
  console.log("Input (long,lat):", lon_input, lat_input);
  const azone = utmzone_from_lon(lon_input);
  console.log(`UTM zone from longitude: ${azone}`);
  console.log("AUTO projection definition:", proj4_setdef(lon_input));
  
  // define proj4_defs for easy uses
  // "EPSG:4326" for long/lat degrees, no projection
  // "EPSG:AUTO" for UTM 'auto zone' projection
  proj4.defs([
  [
    "EPSG:4326",
    "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"
  ],
  ["EPSG:AUTO", proj4_setdef(lon_input)]]);
 
  // usage:
  // conversion from (long/lat) to UTM (E/N)
  const en_m = proj4("EPSG:4326", "EPSG:AUTO", [lon_input, lat_input]);
  const e4digits = en_m[0].toFixed(4); //easting
  const n4digits = en_m[1].toFixed(4); //northing
  console.log(`Zone ${azone}, (E,N) m: ${e4digits}, ${n4digits}`);
  
  // inversion from (E,N) to (long,lat)
  const lonlat_chk = proj4("EPSG:AUTO", "EPSG:4326", en_m);
  console.log("Inverse check:", lonlat_chk);
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.2/proj4.js"></script>


2
投票

我认为您必须为 proj4 投影指定投影区域信息才能使用该库。如果没有区域,它不是有效的 proj4 投影。

这是关于如何从经度/纬度识别区域的问题

这里有两个例子:[1][2]

js代码可以自行查看


0
投票

swatchai 的答案大部分是正确的,但它不能正确地处理多个区域。以下是修改后的版本,其中包含不同区域/半球(北与南)的示例:

  function utmzone_from_lon(lon_deg) {
    //get utm-zone from longitude degrees
    return parseInt(((lon_deg+180)/6)%60)+1;
  }
  
  // modified to account for N vs S
  function proj4_setdef(lon_deg, lat_deg=0) {
    //get UTM projection definition from longitude
    const utm_zone = utmzone_from_lon(lon_deg);
    const isSouth = lat_deg < 0 ? ' +south' : '';
    const zdef = `+proj=utm +zone=${utm_zone}${isSouth} +datum=WGS84 +units=m +no_defs`;
    return zdef;
  }
  
  // computation test
  let lon_input = 95.99;
  let lat_input = 15.15;
  console.log("Input (long,lat):", lon_input, lat_input);
  const azone = utmzone_from_lon(lon_input);
  console.log(`UTM zone from longitude: ${azone}`);
  console.log("AUTO projection definition:", proj4_setdef(lon_input));
  
  // define proj4_defs for easy uses
  // "EPSG:4326" for long/lat degrees, no projection
  // "EPSG:AUTO" for UTM 'auto zone' projection
  //
  // note: this only works for *one* zone at a time (46N in this case)
  // every zone needs a separate def
  var utmAuto = 'AUTO';

  proj4.defs([
  [
    "EPSG:4326",
    "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"
  ],
  [utmAuto, proj4_setdef(lon_input)]]);

  // register the standard projection strings for a few UTM zones for checking
  proj4.defs("EPSG:32646","+proj=utm +zone=46 +datum=WGS84 +units=m +no_defs +type=crs");
  proj4.defs("EPSG:32647","+proj=utm +zone=47 +datum=WGS84 +units=m +no_defs +type=crs");
  proj4.defs("EPSG:32648","+proj=utm +zone=48 +datum=WGS84 +units=m +no_defs +type=crs");
  proj4.defs("EPSG:32748","+proj=utm +zone=48 +south +datum=WGS84 +units=m +no_defs +type=crs");

  // https://epsg.io/32647
  // 32647 == 47N - 96.0 0.0 to 102.0 84.0
  // 32648 == 48N - 102.0 0.0 to 108.0 84.0
  // 32748 == 48S - 102.0 -80.0 to 108.0 0.0
  var test46N = [95.99, 15.15];
  var test47N = [100.99, 15.15];
  var test48N = [105.99, 15.15];
  var test48S = [105.99, -15.15];

  var proj46N = proj4_setdef(...test46N);
  var proj47N = proj4_setdef(...test47N);
  var proj48N = proj4_setdef(...test48N);
  var proj48S = proj4_setdef(...test48S);

  console.log("test 46N, values below should match");
  console.log(proj4('EPSG:4326', utmAuto, test46N));
  console.log(proj4('EPSG:4326', proj46N, test46N));
  console.log(proj4('EPSG:4326', 'EPSG:32646', test46N));

  console.log("test 47N, values below should match (except the first row)");
  console.log(proj4('EPSG:4326', utmAuto, test47N)); // this will be wrong since utmAuto is only defined for 46N
  console.log(proj4('EPSG:4326', proj47N, test47N));
  console.log(proj4('EPSG:4326', 'EPSG:32647', test47N));

  console.log("test 48N, values below should match");
  console.log(proj4('EPSG:4326', proj48N, test48N));
  console.log(proj4('EPSG:4326', 'EPSG:32648', test48N));

 console.log("test 48S, values below should match (except the first row)");
  console.log(proj4('EPSG:4326', proj48N, test48S)); // N vs S makes a difference
  console.log(proj4('EPSG:4326', proj48S, test48S));
  console.log(proj4('EPSG:4326', 'EPSG:32748', test48S));
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.2/proj4.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.