OpenStreetMap

Скрипт создания спиральной башни Эволюция в Москва-Сити н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)};
}

}

Location: Дорогомилово, Москва, Западный административный округ, Москва, Центральный федеральный округ, 121165, РФ

Comment from molnike on 6 January 2018 at 15:41

только building:min_level вместо building:level

Login to leave a comment