目录

 

 

系统运行截图

所使用的技术

前端

后端

Geoserver

数据库


 

系统运行截图

输入一个城市,比如乌鲁木齐,就会生成一个黄色的圆环,并且直接定位到那边!

点击左下角的table内的数据,也可以定位:

这里地图界面是飞过去的,来个动态图(这里GIF针数,不太好):

 

这里目前提供了web版的系统,本人新电脑还没到,等到了,就准备写一个C++|Qt版本的本地GIS定位系统,目前的电脑坚持了5年了,系统重来没有恢复过,现在已经不太好使用了,等新电脑来到时候就可以出一个C++版本的本地GIS定位系统!

 

所使用的技术

这里后端使用的是java的spring boot;

前端框架是vue-cli,输入框等表格使用的element ui。找到地带后黄色的圈使用的是echarts,地图在web显示使用的是leaflet。

这里前后端是分离的。前端使用axios向后端请求数据。

本地GIS使用Geoserver作为服务器。而地图素材使用全能电子地图下载器,下载的 谷歌 地图。

地理坐标等相关信息存储在mysql数据库中。

 

 

前端

这里使用的大框架是vue-cli,控件等使用的element ui,找到地带后黄色的圈使用的是echarts,地图在web显示使用的是leaflet。

这里点一下关键的知识点,把leaflet官方的WMTS瓦块地图插件在vue cli中使用

          /***
           * 插件移植开始
           */

          $L.TileLayer.WMTS = $L.TileLayer.extend({
            defaultWmtsParams: {
              service: 'WMTS',
              request: 'GetTile',
              version: '1.0.0',
              layer: '',
              style: '',
              tilematrixset: '',
              format: 'image/jpeg'
            },

            initialize: function (url, options) { // (String, Object)
              this._url = url;
              let lOptions= {};
              let cOptions = Object.keys(options);
              cOptions.forEach(element=>{
                lOptions[element.toLowerCase()]=options[element];
              });
              let wmtsParams = $L.extend({}, this.defaultWmtsParams);
              let tileSize = lOptions.tileSize || this.options.tileSize;
              if (lOptions.detectRetina && $L.Browser.retina) {
                wmtsParams.width = wmtsParams.height = tileSize * 2;
              } else {
                wmtsParams.width = wmtsParams.height = tileSize;
              }
              for (let i in lOptions) {
                // all keys that are in defaultWmtsParams options go to WMTS params
                if (wmtsParams.hasOwnProperty(i) && i!="matrixIds") {
                  wmtsParams[i] = lOptions[i];
                }
              }
              this.wmtsParams = wmtsParams;
              this.matrixIds = options.matrixIds||this.getDefaultMatrix();
              $L.setOptions(this, options);
            },

            onAdd: function (map) {
              this._crs = this.options.crs || map.options.crs;
              $L.TileLayer.prototype.onAdd.call(this, map);
            },

            getTileUrl: function (coords) { // (Point, Number) -> String
              let tileSize = this.options.tileSize;
              let nwPoint = coords.multiplyBy(tileSize);
              nwPoint.x+=1;
              nwPoint.y-=1;
              let sePoint = nwPoint.add(new $L.Point(tileSize, tileSize));
              let zoom = this._tileZoom;
              let nw = this._crs.project(this._map.unproject(nwPoint, zoom));
              let se = this._crs.project(this._map.unproject(sePoint, zoom));
              let tilewidth = se.x-nw.x;
              let ident = this.matrixIds[zoom].identifier;
              let tilematrix = this.wmtsParams.tilematrixset + ":" + ident;
              let X0 = this.matrixIds[zoom].topLeftCorner.lng;
              let Y0 = this.matrixIds[zoom].topLeftCorner.lat;
              let tilecol=Math.floor((nw.x-X0)/tilewidth);
              let tilerow=-Math.floor((nw.y-Y0)/tilewidth);
              let url = $L.Util.template(this._url, {s: this._getSubdomain(coords)});
              return url + $L.Util.getParamString(this.wmtsParams, url) + "&tilematrix=" + tilematrix + "&tilerow=" + tilerow +"&tilecol=" + tilecol;
            },

            setParams: function (params, noRedraw) {
              $L.extend(this.wmtsParams, params);
              if (!noRedraw) {
                this.redraw();
              }
              return this;
            },

            getDefaultMatrix : function () {
              /**
               * the matrix3857 represents the projection
               * for in the IGN WMTS for the google coordinates.
               */
              let matrixIds3857 = new Array(22);
              for (let i= 0; i<22; i++) {
                matrixIds3857[i]= {
                  identifier    : "" + i,
                  topLeftCorner : new $L.LatLng(20037508.3428,-20037508.3428)
                };
              }
              return matrixIds3857;
            }
          });

          $L.tileLayer.wmts = function (url, options) {
            return new $L.TileLayer.WMTS(url, options);
          };


          /***
           * 插件移植结束
           */

这里要记得导入:

    import "leaflet/dist/leaflet.css"
    import $L from "leaflet"

后面是使用axios向后端请求数据

    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {

            axios.get('http://127.0.0.1:8080/ChinaCity/SingleCity?cityName=' + this.ruleForm.cityName).then((res) =>{

              //console.log(res);
              let emitData = {id: -1, x: -1, y: -1};
              emitData.id = res.data.data.id;
              emitData.x = res.data.data.x;
              emitData.y = res.data.data.y;
              // console.log(emitData)
              this.$emit('GoGIS', emitData);
            });
          }
        });
      }
    }

这里要注意跨域的问题,解决跨域的问题方法很多,在此不再再说明。

 

后端

后端使用的Java的Spring boot,其他可以用浏览器,使用ORM技术,使得开发简单,具体使用的持久层框架为JPA。

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/***
 * 中国城市地理坐标
 */
@Entity
@Data
@Table(name = "china_city")
public class ChinaCity {

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "name")
    private String name;

    @Column(name = "coordX")
    private Float coordX;

    @Column(name = "coordY")
    private Float coordY;

    public ChinaCity() {
    }

    public ChinaCity(Integer id, String name, Float coordX, Float coordY) {

        this.id = id;
        this.name = name;
        this.coordX = coordX;
        this.coordY = coordY;
    }
}

这里来试试请求

乌鲁木齐的请求:

数据从哪里来的,具体将会在数据库中提到!

 

Geoserver

这里使用了Geoserver搭建了一个中国地图的GIS服务:

这里采用的是谷歌EPSG900913的坐标系统,如何去搭建以及如何下载地图,参考本人这篇博文:

https://blog.csdn.net/qq78442761/article/details/100581622

在这里,本人就不再重复说明了!

 

 

数据库

这里的数据库数据是从百度中下载的,自己稍微修改了下:

但百度上的不太靠谱,有错别字,而且精度不太好,小数点后面的位数太少了!

然后本人写了一个C++的小程序,把这个文件,直接导入到了MySQL数据库,具体如下:

#include <QCoreApplication>
#include <QFile>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QVector>
#include <QSqlQuery>

struct CityData;
static QVector<CityData*> cityVec;

struct CityData{

    QString name = "null";
    float x = -1.0;
    float y = -1.0;
};

void insertToMySQL(){

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("XXX.XXX.XXX.XXX");
    db.setDatabaseName("XXXX");
    db.setUserName("XXX");
    db.setPassword("XXX");
    if(!db.open()){

        qDebug() << "The database opend failed : " << db.lastError().text();
        return;
    }

    for(int i = 0; i < cityVec.size(); i++){

        QSqlQuery query;
        QString sql = QString("insert into giscoord.chinacity(name, coordX, coordY) values('%1', %2, %3)")
                .arg(cityVec[i]->name).arg(cityVec[i]->x).arg(cityVec[i]->y);
        if(!query.exec(sql)){

                qDebug() << query.lastError().text();
        }
    }

    qDebug() << "insert over!";
    db.close();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);


    QFile file("C:\\Users\\Administrator\\Desktop\\demo2.csv");
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){

        return -1;
    }


    while(!file.atEnd()){

        QStringList listStr = QString::fromLocal8Bit(file.readLine()).remove("\n").split(",");
        CityData *city = new CityData;
        city->name = listStr[0].toUtf8();
        city->x = listStr[1].toFloat();
        city->y = listStr[2].toFloat();

        cityVec.append(city);

    }

    file.close();


    insertToMySQL();

    for(int i = 0; i < cityVec.size(); i++){

        delete cityVec[i];
    }
    cityVec.clear();

    qDebug() << "programme over!";

    return a.exec();
}

 

Logo

前往低代码交流专区

更多推荐