Скрипт создания спиральной башни Эволюция в Москва-Сити нa java для импорт в JOSM
Posted by molnike on 4 January 2018 in Russian (Русский).package com.moilnike.createosm;
public class Create_Building_Evolution {
public static void main(String[] args) {
int steps = 17;
float angle_start = -30;
float angle_step = 8.9f;
float height_step = 14.5f;
int level_step = 3;
float width_gipo_in17of256 = 40;
float gps_x = 37.5418189463f;
float gps_y = 55.7483475707f;
float[] tile_xy = gps_to_tile(gps_x, gps_y, 17);
int start_n = 40000;
int start_w = 50000;
angle_start +=45;
width_gipo_in17of256 = (float)(((double)width_gipo_in17of256)*Math.sqrt(2)/256.0);
System.out.println("<?xml version='1.0' encoding='UTF-8'?>");
System.out.println("<osm version='0.6' generator='JOSM'>");
System.out.println("<bounds minlat='55.74798' minlon='37.54120' maxlat='55.74870' maxlon='37.54243' origin='CGImap 0.6.0 (31694 thorn-03.openstreetmap.org)' />");
for(int j=0;j<steps;j++){
for(int k=0;k<4;k++){
int id = start_n + j*4+k;
float ang = angle_start+angle_step*j+k*90;
float[] dxy = rotatePoint(width_gipo_in17of256,0,0,0,ang);
float[] gps = tile_to_GPS(tile_xy[0]+dxy[0],tile_xy[1]+dxy[1],17);
System.out.println(" <node id='-"+id+"' action='modify' lat='"+gps[1]+"' lon='"+gps[0]+"' />");
}
}
for(int j=0;j<steps;j++){
System.out.println(" <way id='-"+(start_w+j)+"' action='modify'>");
for(int k=0;k<5;k++){
int k2=k;
if(k==4){
k2=0;
}
int id = start_n + j*4+k2;
System.out.println(" <nd ref='-"+id+"' />");
}
if(j>0){
System.out.println(" <tag k='building:level' v='"+(j*level_step)+"' />");
System.out.println(" <tag k='min_height' v='"+(j*height_step)+"' />");
}
System.out.println(" <tag k='building:levels' v='"+((j+1)*level_step)+"' />");
System.out.println(" <tag k='height' v='"+((j+1)*height_step)+"' />");
System.out.println(" <tag k='building:part' v='yes' />");
System.out.println(" </way>");
}
System.out.println("</osm>");
}
public static float[] tile_to_GPS(float tile_x_pos, float tile_y_pos, int zoom) {
try{
double n = Math.pow(2.0, zoom);
double b = Math.PI - 2.0 * Math.PI * tile_y_pos / n;
double lat = 180.0 / Math.PI * Math.atan(0.5 * (Math.exp(b) - Math.exp(-b)));
float real_x = (float) (tile_x_pos/n*360.0-180.0);
float real_y = (float) lat;
return new float[]{real_x, real_y};
}catch(Exception ex){}
return new float[]{0, 0};
}
public static float[] gps_to_tile(float world_x, float world_y, int zoom) {
try{
double lat_rad = Math.toRadians(world_y);
double n = Math.pow(2.0, zoom);
double tileX = ((world_x + 180.0) / 360.0) * n;
double log = Math.tan(Math.PI/4f+lat_rad/2f);
double tileY = (1.0 - (Math.log(log) / Math.PI)) * n / 2.0;
return new float[]{(float)tileX, (float)tileY};
}catch(Exception ex){}
return new float[]{0, 0};
}
public static float[] rotatePoint(float px, float py, float p0x, float p0y, float ang){
double angle = ang*Math.PI/180;
float old_x_point = px-p0x;
float old_y_point = py-p0y;
double new_x_point = old_x_point * Math.cos(angle) - old_y_point * Math.sin(angle);
double new_y_point = old_y_point * Math.cos(angle) + old_x_point * Math.sin(angle);
return new float[]{(float)(new_x_point+p0x),(float)(new_y_point+p0y)};
} }
Discussion
Comment from molnike on 6 January 2018 at 15:41
только building:min_level вместо building:level