WorldWind Java version loads shp files and achieves three-dimensional effects

I introduced loading WMS service layer in WorldWind Java version before. If you want to learn, you can read the previous article . WorldWind is a display that implements three-dimensional effects. Of course, loading three-dimensional models is indispensable. I looked through the source code of WorldWind and found that WorldWind supports loading three-dimensional models in KMZ format. This is more precise. If you need to load a KMZ format model, you can leave a message below and the code to load the KMZ format will be sent later. Today I will record loading shape files to achieve three-dimensional effects. Due to the model, it is relatively rough.
First, take a look at the effect after loading:
Insert image description here

1.shape file

The shape file here is a vector file with height, which can be produced using ArcMap. As shown below:
Insert image description here
This is a shape file of an airport. The file attribute table has a column indicating the height of each pixel. As shown below.
Insert image description here
You can see that the attribute table contains a lot of information. Just look at the "hhh" list, which represents the elevation of each pixel. This value is the key to forming a three-dimensional effect. Once you have this file ready, you can start coding.

2. Write code

Paste the code directly:

/*
* 加载带有高度的shape文件,并将高度进行拉伸,形成三维效果
* 2021年11月24日14:14:17
* */
public class ModelLayer {
    private static RenderableLayer layer;                  //三维模型的渲染图层

    //加载三维模型的方法
    public static void init3DModel(WorldWindowGLCanvas wwd, String filePath){
        Shapefile shapefile = new Shapefile(filePath);
        layer = new RenderableLayer();
        layer.setName("model");                           //图层命名为“model”,这个可以自定义
        layer.setPickEnabled(true);

        try {
            while (shapefile.hasNext()) {
                ShapefileRecord record = shapefile.nextRecord();
                layer.addRenderable(makeShape(record));
            }
            wwd.getModel().getLayers().add(layer);
        } finally {
            shapefile.close();
        }
    }

    private static ExtrudedPolygon makeShape(ShapefileRecord record) {
        String IMAGE_PATH = "images/ic_wall.jpg";          //这个是贴图纹理的路径
        Double height = null;                              //每个像素的高度值

        /*
         * 这里需要注意一下,获取到的高度值必须大于0,当有小于等于0的高度值时,
         * 需要将高度值设为0.1即可。且所有值不能忽略,否则会报错
         * */
        Object o = record.getAttributes().getValue("hhh"); //hhh为shape文件中表示高度的字段值。也就是在第一步中提到的表示高程的字段。                                                  
        if (o != null) {
            Double h = Double.parseDouble(o.toString());
            if (h<=0){                                     //如果有小于等于0的值,设为0.1,只要大于0即可。
                h=0.1;
            }
            height=h*20;                                   //将高度值拉高20倍,否则原始的高度值,三维效果不明显
        }

        // 顶部属性
        ShapeAttributes capAttrs = new BasicShapeAttributes();
        capAttrs.setOutlineMaterial(Material.GRAY);
        capAttrs.setInteriorMaterial(Material.LIGHT_GRAY);

        // 边属性
        ShapeAttributes sideAttributes = new BasicShapeAttributes();
        sideAttributes.setInteriorMaterial(Material.LIGHT_GRAY);
        sideAttributes.setOutlineMaterial(Material.DARK_GRAY);
        sideAttributes.setImageSource(IMAGE_PATH);

        // 创建拉伸多边形
        VecBuffer vb = record.getPointBuffer(0);
        gov.nasa.worldwind.render.airspaces.Polygon pgonAirspace = new Polygon(vb.getLocations());                                     //根据点串构建多边形

        //纹理
        ArrayList<String> textures = new ArrayList<String>();
        for (int i = 0; i < pgonAirspace.getLocations().size()-1; i++) {
            textures.add(IMAGE_PATH);
        }

        //给多边形添加上高度和纹理。
        ExtrudedPolygon polygon = new ExtrudedPolygon(pgonAirspace.getLocations(), height, textures);                 //有纹理
        //ExtrudedPolygon polygon = new ExtrudedPolygon(pgonAirspace.getLocations(), height, null);                       //纹理设为null,即可设为无纹理。

        polygon.setCapAttributes(capAttrs);
        polygon.setSideAttributes(sideAttributes);
        polygon.setAltitudeMode(WorldWind.CLAMP_TO_GROUND);
        return polygon;
    }

    /*
    * 移除指定名字的三维模型
    * */
    public static void removeModel(WorldWindowGLCanvas wwd,String name){
        if (wwd.getModel().getLayers().getLayerByName(name)!=null){
            wwd.getModel().getLayers().remove(wwd.getModel().getLayers().getLayerByName(name));
            wwd.redrawNow();
        }
    }
}

This is the code, isn’t it very simple. When using it, just call it directly. There are two parameters, one is the three-dimensional ball and the other is the path of the shape file.

Guess you like

Origin blog.csdn.net/nanjumufeng/article/details/121513804