【JAVAFX 构建中国地图2021最新版】

【JAVAFX 构建中国地图2021最新版】

  • 一直在想中国地图如何能够在界面中实现,查找资料后发现地图的轮廓原来是一堆节点构成.于是中国地图它来了.

  • 中国地图数据来源:http://datav.aliyun.com/tools/atlas/index.html

  • 版本:V3

  • 地图数据版本数据更新于2021.5

  • 地图构建效果:

  • 版本1.0

在这里插入图片描述

  • 版本2.0
    在这里插入图片描述

  • 中国地图数据绘制实现
    地图数据默认绘制的节点是反向的,需要修正处理,同时内蒙古自治区的数据和其他省份的数据在构建格式上有不同.如有其他问题可以留言交流.

package com.liangchao.modelcenter.uisystem.controller.tool;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.liangchao.modelcenter.uisystem.frame.App;
import com.liangchao.modelcenter.utils.ColorUtil;
import com.liangchao.modelcenter.utils.FileUtil;
import com.liangchao.modelcenter.utils.javafx.MouseMove;
import com.liangchao.modelcenter.utils.javafx.SupperController;
import de.felixroske.jfxsupport.FXMLController;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import lombok.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 中国地图图形绘制
 */
@FXMLController
public class ChineseMapUIController extends SupperController {

    @FXML
    private              Label         name;
    @FXML
    private              Label         code;
    @FXML
    private              Label         level;
    @FXML
    private              VBox          infoBox;//信息
    @FXML
    private              AnchorPane    canvas;//绘制面板
    @Autowired
    private              ObjectMapper  objectMapper;
    private              MediaPlayer   mediaPlayer;
    private static       boolean       play           = false;
    private              List<Polygon> polygonList;
    private              Polygon       thisPolygon;
    private static final String        SELECT_POLYGON = "select-polygon";

    @Override
    public void closeHandle() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer = null;
        }

        play = false;
    }

    @Override
    public void openHandle(Object... param) {
        try {
            this.drawChineseMap();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //绑定属性面板拖动
        infoBox.setLayoutX(10);
        infoBox.setLayoutY(10);
        new MouseMove(infoBox).bind();

        this.name.setText("");
        this.code.setText("");
        this.level.setText("");
    }

    /**
     * 绘制地图
     */
    private void drawChineseMap() throws Exception {
        Map  map;
        List list, list1, list2;
        polygonList = new LinkedList<>();
        double scale = 12, w = App.controller().getWinWidth() / 2, w0 = 550, h = App.controller().getWinHeight() / 2;

        h = 670;
        for (Object object : loadMap()) {
            map = (Map) ((Map) object).get("properties");
            // 各块轮廓
            list = (List) ((Map) ((Map) object).get("geometry")).get("coordinates");
            for (Object root : list) {
                // 轮廓节点
                Polygon polygon = new Polygon();
                polygonList.add(polygon);

                Entity entity = new Entity();
                entity.setPolygon(polygon);
                entity.setName(map.get("name").toString());
                entity.setAdcode(map.get("adcode").toString());
                list2 = (List) map.get("center");
                if (list2 != null) {
                    entity.setCenterX((Double) list2.get(0));
                    entity.setCenterY((Double) list2.get(1));
                }
                list2 = (List) map.get("centroid");
                if (list2 != null) {
                    entity.setCentroidX((Double) list2.get(0));
                    entity.setCentroidY((Double) list2.get(1));
                }
                entity.setChildrenNum((Integer) map.get("childrenNum"));
                entity.setLevel(map.get("level") != null ? map.get("level").toString() : null);
                entity.setParentCode(map.get("parent") != null ? (Integer) ((Map) map.get("parent")).get("adcode") : null);
                entity.setSubFeatureIndex((Integer) map.get("subFeatureIndex"));
                list2 = (List) map.get("acroutes");
                if (list2 != null) {
                    entity.setAcroutes((Integer) list2.get(0));
                }

                polygon.getStyleClass().add("polygon");
                polygon.setFill(Color.web(ColorUtil.toHex(), 0.95));
                polygon.setOnMouseClicked(event -> {
                    this.name.setText(entity.getName());
                    this.code.setText(entity.getAdcode());
                    this.level.setText(this.convertLevel(entity.getLevel()));
                });

                list1 = (List) root;
                list  = (List) list1.get(0);

                // 内蒙古自治区 数据在上一级list中 比较特殊
                if (entity.getName().equals("内蒙古自治区")) {
                    list = list1;
                }

                int i = 0;
                for (Object ls : list) {
                    if (ls instanceof ArrayList) {
                        int j = 0;
                        for (Object val : (List) ls) {
                            polygon.getPoints().add(j % 2 != 0 ? h - (Double) val * scale : (Double) val * scale - w0);
                            j++;
                        }
                    } else {
                        System.out.println(ls.getClass().getName() + "  other ");
                    }

                    i++;
                }

                canvas.getChildren().add(polygon);
            }
        }
    }

    public List loadMap() throws Exception {
        //  https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json
        //  http://datav.aliyun.com/tools/atlas/index.html
        //
        //  数据来源于高德开放平台,数据更新于2020.4
        String file = this.getClass().getResource("/chinese_full.json").getFile();
        // 获取第一级数据
        return (List) objectMapper.readValue(FileUtil.file(file), Map.class).get("features");
    }

    /**
     * level 转换
     */
    private String convertLevel(String level) {
        //        country:国家
        //        province:省份(直辖市会在province和city显示)
        //        city:市(直辖市会在province和city显示)
        //        district:区县
        //        street:街道
        String v = null;
        if (level == null) {
            return v;
        }

        switch (level) {
            case "country":
                v = "国家";
                break;
            case "province":
                v = "省份";
                break;
            case "city":
                v = "市";
                break;
            case "district":
                v = "区县";
                break;
            case "street":
                v = "街道";
                break;
        }

        return v;
    }

    /**
     * 播放音乐
     */
    public void playMusicAction(MouseEvent event) {
        if (play) {
            mediaPlayer.stop();
            play = false;
            return;
        }

        Media media2 = new Media(this.getClass().getResource("/audio/chinese.mp3").toString());
        mediaPlayer = new MediaPlayer(media2);
        mediaPlayer.setAudioSpectrumListener((timestamp, duration, magnitudes, phases) -> {

        });
        mediaPlayer.onStoppedProperty().addListener((observable, oldValue, newValue) -> {
            play = false;
        });
        play = true;
        mediaPlayer.play();
    }

    /**
     * 节点数据信息
     */
    @Setter
    @Getter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    public class Entity {
        private String  name;//名称
        private String  adcode;//编码
        private Double  centerX;//中心X
        private Double  centerY;//中心y
        private Double  centroidX;//面心 x
        private Double  centroidY;//面心 y
        private Integer childrenNum; //子节点数量
        private String  level;//级别
        private Integer parentCode; //父编码
        private Integer subFeatureIndex;//子功能索引
        private Integer acroutes;
        private Polygon polygon;//节点
    }
}

  • 如有问题留言交流.
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值