⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmlreflector.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                String filter = (String) requestParams.get("FEATUREID");
                filters = new ArrayList();
                for ( int i = 0; i < layers.length; i++ ) {
                        filters.add(filter);
                }
                filterKey = "featureid";
        }
        
        if ( filters != null && filters.size() != layers.length) {
                throw (IOException) new IOException().initCause(
                        new ServiceException( layers.length + " layers specified, but " + filters.size() + " filters")
                        );
        }
        
        //set the content disposition
        StringBuffer filename = new StringBuffer();
        for ( int i = 0; i < layers.length; i++ ) {
            String name = layers[i].getName();
            
            //strip off prefix
            int j = name.indexOf(':');
            if ( j > -1 ) {
                    name = name.substring( j + 1 );
            }
            
            filename.append(name + "_");
        }
        filename.setLength(filename.length()-1);
        
        response.setHeader("Content-Disposition", 
                        "attachment; filename=" + filename.toString() + ".kml");
        
        // we use the mandatory SRS value of 4326 (lat/lon)
        serviceRequest.setFormat(KML_MIME_TYPE); // output mime type of KML

        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        sb.append("<kml xmlns=\"http://earth.google.com/kml/2.0\">\n");

        sb.append("<Folder>\n");
        
        String proxifiedBaseUrl = RequestUtils.baseURL(request);
        GeoServer gs = (GeoServer)GeoServerExtensions.extensions(GeoServer.class).get(0);
        proxifiedBaseUrl = RequestUtils.proxifiedBaseURL(proxifiedBaseUrl,gs.getProxyBaseUrl());
          
          Envelope layerbbox = null;

        // make a network link for every layer
        for (int i = 0; i < layers.length; i++) {
            //if (layers[i].getType() == MapLayerInfo.TYPE_VECTOR) {
            String style = "&styles=" + layers[i].getDefaultStyle().getName();

            if ((styles != null) && (styles.length >= (i + 1))) { // if the user specified styles
                style = "&styles=" + styles[i].getName(); // use them, else we use the default style
            }

            String filter = (String) (filters != null ? filters.get(i) : null);
            if ( filter != null ) {
                filter = "&" + filterKey + "=" + filter;
            }
            else {
                filter = "";
            }
            if (serviceRequest.getSuperOverlay()) {
                Envelope bbox = serviceRequest.getBbox();

                sb.append("<NetworkLink>\n");
                sb.append("<name>" + layers[0].getName() + "</name>\n");
                sb.append("<Region>");
                sb.append("<LatLonAltBox>");
                sb.append("<north>" + bbox.getMaxY() + "</north>");
                sb.append("<south>" + bbox.getMinY() + "</south>");
                sb.append("<east>" + bbox.getMaxX() + "</east>");
                sb.append("<west>" + bbox.getMinX() + "</west>");
                sb.append("</LatLonAltBox>");
                sb.append("<Lod>");
                sb.append("<minLodPixels>256</minLodPixels>");
                sb.append("<maxLodPixels>-1</maxLodPixels>");
                sb.append("</Lod>");
                sb.append("</Region>");

                sb.append("<Link>\n");
                sb.append("<href><![CDATA[" + proxifiedBaseUrl
                    + "/wms?service=WMS&request=GetMap&format=application/vnd.google-earth.kml+XML"
                    + "&width=" + WIDTH + "&height=" + HEIGHT + "&srs=" + SRS + "&layers="
                    + layers[i].getName() + style + "&bbox=" + (String) requestParams.get("BBOX")
                    + filter
                    + "&legend=" + String.valueOf(serviceRequest.getLegend())
                    + "&superoverlay=true]]></href>\n");
                sb.append("<viewRefreshMode>onRegion</viewRefreshMode>\n");

                sb.append("</Link>\n");
                sb.append("</NetworkLink>\n");
            } else {

//               Envelope le = (layers[i].getFeature() == null ? layers[i].getBoundingBox() : layers[i].getFeature().getLatLongBoundingBox());

              Envelope le = layers[i].getLatLongBoundingBox();
              if (layerbbox == null){
                layerbbox = new Envelope(le);
              } else {
                layerbbox.expandToInclude(le);
              }
              
                sb.append("<NetworkLink>\n");
                sb.append(getLookAt(le));
                sb.append("<name>" + layers[i].getName() + "</name>\n");
                sb.append("<open>1</open>\n");
                sb.append("<visibility>1</visibility>\n");
                sb.append("<Url>\n");
                sb.append("<href><![CDATA[" + proxifiedBaseUrl
                    + "/wms?service=WMS&request=GetMap&format=application/vnd.google-earth.kmz+XML"
                    + "&width=" + WIDTH + "&height=" + HEIGHT + "&srs=" + SRS + "&layers="
                    + layers[i].getName() + style + filter // optional
                    + "&KMScore=" + serviceRequest.getKMScore() + "&KMAttr="
                    + String.valueOf(serviceRequest.getKMattr()) + "&legend="
                    + String.valueOf(serviceRequest.getLegend()) + "]]></href>\n");
                sb.append("<viewRefreshMode>onStop</viewRefreshMode>\n");
                sb.append("<viewRefreshTime>" + REFRESH + "</viewRefreshTime>\n");
                sb.append("</Url>\n");
                sb.append("</NetworkLink>\n");
            }
        }

          sb.append(getLookAt(layerbbox));
          
        sb.append("</Folder>\n");

        sb.append("</kml>\n");

        byte[] kml_b = sb.toString().getBytes();
        out.write(kml_b);
        out.flush();
    }

  private String getLookAt(Envelope e){
    double lon1 = e.getMinX();
    double lat1 = e.getMinY();
    double lon2 = e.getMaxX();
    double lat2 = e.getMaxY();
    
    double R_EARTH = 6.371 * 1000000; // meters
    double VIEWER_WIDTH = 22 * Math.PI / 180; // The field of view of the google maps camera, in radians
    double[] p1 = getRect(lon1, lat1, R_EARTH);
    double[] p2 = getRect(lon2, lat2, R_EARTH);
    double[] midpoint = new double[]{
      (p1[0] + p2[0])/2,
        (p1[1] + p2[1])/2,
        (p1[2] + p2[2])/2
    };
    
    midpoint = getGeographic(midpoint[0], midpoint[1], midpoint[2]);
    
    // averaging the longitudes; using the rectangular coordinates makes the calculated center tend toward the corner that's closer to the equator. 
    midpoint[0] = ((lon1 + lon2)/2); 
    
    double distance = distance(p1, p2);
    
    double height = distance/ (2 * Math.tan(VIEWER_WIDTH));
    
    LOGGER.fine("lat1: " + lat1 + "; lon1: " + lon1);
    LOGGER.fine("lat2: " + lat2 + "; lon2: " + lon2);
    LOGGER.fine("latmid: " + midpoint[1] + "; lonmid: " + midpoint[0]);
    
    
    return "<LookAt id=\"geoserver\">" + 
      "  <longitude>" + ((lon1 + lon2)/2) +  "</longitude>      <!-- kml:angle180 -->" +
      "  <latitude>"+midpoint[1]+"</latitude>        <!-- kml:angle90 -->" +
    "  <altitude>0</altitude>       <!-- double --> " +
    "  <range>"+distance+"</range>              <!-- double -->" +
    "  <tilt>0</tilt>               <!-- float -->" +
    "  <heading>0</heading>         <!-- float -->" +
    "  <altitudeMode>clampToGround</altitudeMode> " +
    "  <!--kml:altitudeModeEnum:clampToGround, relativeToGround, absolute -->" +
      "</LookAt>";
  }
  
  private double[] getRect(double lat, double lon, double radius){
    double theta = (90 - lat) * Math.PI/180;
    double phi   = (90 - lon) * Math.PI/180;
    
    double x = radius * Math.sin(phi) * Math.cos(theta);
    double y = radius * Math.sin(phi) * Math.sin(theta);
    double z = radius * Math.cos(phi);
    return new double[]{x, y, z};
  }
  
  private double[] getGeographic(double x, double y, double z){
    double theta, phi, radius;
    radius = distance(new double[]{x, y, z}, new double[]{0,0,0});
    theta = Math.atan2(Math.sqrt(x * x + y * y) , z);
    phi = Math.atan2(y , x);
    
    double lat = 90 - (theta * 180 / Math.PI);
    double lon = 90 - (phi * 180 / Math.PI);
    
    return new double[]{(lon > 180 ? lon - 360 : lon), lat, radius};
  }
  
  private double distance(double[] p1, double[] p2){
    double dx = p1[0] - p2[0];
    double dy = p1[1] - p2[1];
    double dz = p1[2] - p2[2];
    return Math.sqrt(dx * dx + dy * dy + dz * dz);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -