Last active
June 2, 2019 14:10
-
-
Save seraekim/8bbbac819f304cc4dde5db909f89d7af to your computer and use it in GitHub Desktop.
convert among LambertConformalConic XY Grid, Longitude/Latitude and Address
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.srkim.test; | |
import java.io.IOException; | |
import java.io.UnsupportedEncodingException; | |
import java.net.MalformedURLException; | |
import java.net.URL; | |
import java.net.URLEncoder; | |
import java.nio.charset.Charset; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.apache.commons.io.IOUtils; | |
import org.json.JSONArray; | |
import org.json.JSONException; | |
import org.json.JSONObject; | |
/** | |
* can convert among LambertConformalConic XY Grid, Longitude/Latitude and | |
* Address. need to import apache commons io and org.json provided examples via | |
* class main method. | |
* | |
* @author srkim | |
* | |
*/ | |
public class LambertConformalConicProj { | |
final static double PI = Math.PI; | |
final static double DEG_TO_RAD = PI / 180.0; | |
final static double RAD_TO_DEG = 180.0 / PI; | |
/** | |
* GRID SPACING [km] | |
*/ | |
final static double SPACING = 5; | |
/** | |
* RADIUS OF EARTH [km] | |
*/ | |
final static double RADIUS = 6371 / SPACING; | |
/** | |
* STANDARD LATITUDE 1 | |
*/ | |
final static double STAND_LAT1 = 30.0 * DEG_TO_RAD; | |
/** | |
* STANDARD LATITUDE 2 | |
*/ | |
final static double STAND_LAT2 = 60.0 * DEG_TO_RAD; | |
/** | |
* LONGITUDE OF REFERENCE POINT | |
*/ | |
final static double REF_LON = 126.0 * DEG_TO_RAD; | |
/** | |
* LATITUDE OF REFERENCE POINT | |
*/ | |
final static double REF_LAT = 38.0 * DEG_TO_RAD; | |
/** | |
* X COORDINATE OF REFERENCE POINT | |
*/ | |
final static double REF_X = 43; | |
/** | |
* Y COORDINATE OF REFERENCE POINT | |
*/ | |
final static double REF_Y = 136; | |
static double sn = Math.tan(PI * 0.25 + STAND_LAT2 * 0.5) / Math.tan(PI * 0.25 + STAND_LAT1 * 0.5); | |
static double sf = Math.tan(PI * 0.25 + STAND_LAT1 * 0.5); | |
static double ro = Math.tan(PI * 0.25 + REF_LAT * 0.5); | |
static { | |
sn = Math.log(Math.cos(STAND_LAT1) / Math.cos(STAND_LAT2)) / Math.log(sn); | |
sf = Math.pow(sf, sn) * Math.cos(STAND_LAT1) / sn; | |
ro = RADIUS * sf / Math.pow(ro, sn); | |
} | |
/* | |
* from user's data. | |
*/ | |
double x, y, lon, lat; | |
List<Object> address; | |
public void setXy(double x, double y) { | |
this.x = x; | |
this.y = y; | |
} | |
public void setLonlat(double lon, double lat) { | |
this.lon = lon; | |
this.lat = lat; | |
} | |
public void setAddress(String address) { | |
List<Object> list = new ArrayList<>(); | |
list.add(address); | |
this.address = list; | |
} | |
public void setAddress(List<Object> address) { | |
this.address = address; | |
} | |
public List<Object> getAddress() { | |
return address; | |
} | |
public void lonlat2Xy() { | |
double ra = Math.tan(PI * 0.25 + lat * DEG_TO_RAD * 0.5); | |
ra = RADIUS * sf / Math.pow(ra, sn); | |
double theta = lon * DEG_TO_RAD - REF_LON; | |
if (theta > PI) | |
theta = theta - (2.0 * PI); | |
if (theta < -PI) | |
theta = theta + (2.0 * PI); | |
theta = theta * sn; | |
x = (ra * Math.sin(theta)) + REF_X; | |
x = Math.round(x); | |
y = (ro - ra * Math.cos(theta)) + REF_Y; | |
y = Math.round(y); | |
log(x + " : " + y); | |
} | |
public void lonlat2Address() { | |
JSONObject jObj = requestApi("latlng=" + lat + "," + lon); | |
JSONArray results = jObj.getJSONArray("results"); | |
List<Object> addressArray = new ArrayList<>(); | |
for (int i = 0; i < results.length(); i++) { | |
List<Object> types = results.getJSONObject(i).getJSONArray("address_components").getJSONObject(0) | |
.getJSONArray("types").toList(); | |
for (Object o : types) { | |
if ("sublocality_level_2".equals(o)) { | |
addressArray.add(results.getJSONObject(i).getString("formatted_address")); | |
} | |
} | |
} | |
address = addressArray; | |
log(addressArray); | |
} | |
public void xy2Lonlat() { | |
double xn = x - REF_X; | |
double yn = ro - y + REF_Y; | |
double ra = Math.sqrt(xn * xn + yn * yn); | |
if (sn < 0.0) | |
ra = -ra; | |
double alat = Math.pow((RADIUS * sf / ra), (1.0 / sn)); | |
double theta = 0; | |
alat = 2.0 * Math.atan(alat) - PI * 0.5; | |
if (Math.abs(xn) <= 0.0) { | |
theta = 0.0; | |
} else { | |
if (Math.abs(yn) <= 0.0) { | |
theta = PI * 0.5; | |
if (xn < 0.0) | |
theta = -theta; | |
} else { | |
theta = Math.atan2(xn, yn); | |
} | |
} | |
double alon = theta / sn + REF_LON; | |
lon = alon * RAD_TO_DEG; | |
lat = alat * RAD_TO_DEG; | |
log(lon + " : " + lat); | |
} | |
public void xy2Address() { | |
xy2Lonlat(); | |
lonlat2Address(); | |
} | |
public void address2Lonlat() { | |
JSONObject jObj = requestApi("address=" + urlEncode(address.get(0))); | |
JSONArray results = jObj.getJSONArray("results"); | |
JSONObject loc = results.getJSONObject(results.length() - 1).getJSONObject("geometry") | |
.getJSONObject("location"); | |
lon = loc.getDouble("lng"); | |
lat = loc.getDouble("lat"); | |
log(lon + " : " + lat); | |
} | |
public void address2Xy() { | |
address2Lonlat(); | |
lonlat2Xy(); | |
} | |
public static void main(String[] args) { | |
LambertConformalConicProj s = new LambertConformalConicProj(); | |
// can set initially lng/lat, xy, address(String or List) | |
s.setLonlat(126.9156168, 37.476128); | |
// 1. CONVERT LONLAT TO XY | |
s.lonlat2Xy(); | |
// 2. INPUT LONGITUDE AND LATITUDE, OUTPUT address | |
s.lonlat2Address(); | |
// 3. INPUT XY, OUTPUT LONGITUDE AND LATITUDE | |
s.xy2Lonlat(); | |
// 4. INPUT XY, OUTPUT ADDRESS | |
s.xy2Address(); | |
// 5. INPUT ADDRESS, OUTPUT LONGITUDE AND LATITUDE | |
s.address2Lonlat(); | |
// 6. INPUT ADDRESS, OUTPUT XY | |
s.address2Xy(); | |
} | |
/* | |
* commons,,,, | |
*/ | |
private JSONObject requestApi(String params) { | |
String apiUrl = "https://maps.googleapis.com/maps/api/geocode/json?language=ko&"; | |
JSONObject jObj = null; | |
try { | |
jObj = new JSONObject(IOUtils.toString(new URL(apiUrl + params), Charset.forName("UTF-8"))); | |
log(apiUrl + params); | |
} catch (JSONException e) { | |
e.printStackTrace(); | |
} catch (MalformedURLException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return jObj; | |
} | |
private String urlEncode(Object obj) { | |
String result = null; | |
try { | |
result = URLEncoder.encode((String) obj, "UTF-8"); | |
} catch (UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
return result; | |
} | |
private void log(Object msg) { | |
System.out.println(Thread.currentThread().getStackTrace()[2] + " " + msg); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment