从零开始,构建电子地图网站:0_9_web+InitializingBean启动加载本地缓存

我有点忘了当初的宏愿了,所以要回到网站上看看,http://worldmap.harvard.edu/maps/chinaX

 

先下载个有道翻译,看下左侧的Overlays,忽然发现除了《中国历史地图集》上有的政区和治所沿革外。还有很多自然地理、农业地理、军事地理,人口变迁、海岸线变迁、黄河变迁的图层,这些数据都没有。

那还是先用现有的数据,参考《中国历史地图集》的索引顺序,以朝代划分图层吧。

商周(春秋战国)、秦、汉(西汉东汉)、晋(三国西晋东晋)、唐、五代十国、宋、元、明、清。

图层展示是用朝代划分的,点击可见覆盖物的时候,弹出infowindow,显示属性。

 

先看下数据量级,多的话,就分开,不多的话,就全部返给前端。

v6_time_cnty_pts_utf_wgs84这张表对象有10522个。

v6_time_pref_pts_utf_wgs84 这张表对象有5226个。

v6_time_pref_pgn_utf_wgs84这张表对象有3830个。

那么还是按照年代分吧。

商周:<-221

秦:-220~-202

汉:-201~220

晋、三国:221~589

唐、隋:590~907

五代十国:908~960

宋:961~1276

元1277~1368

明1369~1644

清1645~1840

 

开始对工程进行改造。

一、model

D:\gismap\java\gismap\src\main\java\com\history\gismap\model\GeometryModel.java

首先把model中的类改成GeometryModel,以兼容更多的geometry类型。

package com.history.gismap.model;



import com.vividsolutions.jts.geom.Geometry;

import lombok.Getter;

import lombok.Setter;

import lombok.ToString;



@Getter

@Setter

@ToString

public class GeometryModel {

    private Integer gId;

    private String namePy;

    private String nameCh;

    private String nameFt;

    private String presLoc;

    private String typePy;

    private String typeCh;

    private String levRank;

    private Integer begYr;

    private String begRule;

    private Integer endYr;

    private String endRule;

    private String geoSrc;

    private String compiler;

    private String gecomplr;

    private String checker;

    private String entDate;

    private String begChgTy;

    private String endChgTy;

    private Geometry geometry;

}

 

 

二、dao

D:\gismap\java\gismap\src\main\java\com\history\gismap\dao\MapDao.java

我们只需要查询,并查询三张表。

把不必要的删掉,补充需要的。

package com.history.gismap.dao;

import com.history.gismap.model.GeometryModel;

import org.apache.ibatis.annotations.Param;

import org.springframework.stereotype.Service;

@Service

public interface MapDao {

    GeometryModel getCntyPoint(@Param("gId") Integer gId);

    GeometryModel getPrefPoint(@Param("gId") Integer gId);

    GeometryModel getprefPolygon(@Param("gId") Integer gId);

}

 

 

三、Mapper

 

D:\gismap\java\gismap\src\main\resources\mapper\HistoryGISMapper.xml

 

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.history.gismap.dao.MapDao" >

    <resultMap id="geometryModelResult" type="com.history.gismap.model.GeometryModel">

        <result property="gId" column="gid" jdbcType="BIGINT"/>

        <result property="namePy" column="name_py" jdbcType="VARCHAR"/>

        <result property="nameCh" column="name_ch" jdbcType="VARCHAR"/>

        <result property="nameFt" column="name_ft" jdbcType="VARCHAR"/>

        <result property="presLoc" column="pres_loc" jdbcType="VARCHAR"/>

        <result property="typePy" column="type_py" jdbcType="VARCHAR"/>

        <result property="typeCh" column="type_ch" jdbcType="VARCHAR"/>

        <result property="levRank" column="lev_rank" jdbcType="VARCHAR"/>

        <result property="begYr" column="beg_yr" jdbcType="BIGINT"/>

        <result property="begRule" column="beg_rule" jdbcType="VARCHAR"/>

        <result property="endYr" column="end_yr" jdbcType="BIGINT"/>

        <result property="endRule" column="end_rule" jdbcType="VARCHAR"/>

        <result property="geoSrc" column="geo_src" jdbcType="VARCHAR"/>

        <result property="compiler" column="compiler" jdbcType="VARCHAR"/>

        <result property="gecomplr" column="gecomplr" jdbcType="VARCHAR"/>

        <result property="checker" column="checker" jdbcType="VARCHAR"/>

        <result property="entDate" column="ent_date" jdbcType="VARCHAR"/>

        <result property="begChgTy" column="beg_chg_ty" jdbcType="VARCHAR"/>

        <result property="endChgTy" column="end_chg_ty" jdbcType="VARCHAR"/>

        <result property="geometry" column="geom" typeHandler="com.history.gismap.mybatis.GeometryTypeHandler"/>

    </resultMap>

    <sql id="CNTY_PTS">

        v6_time_cnty_pts_utf_wgs84

    </sql>

    <sql id="PREF_PTS">

        v6_time_pref_pts_utf_wgs84

    </sql>

    <sql id="PREF_PGN">

        v6_time_pref_pgn_utf_wgs84

    </sql>

    <sql id="BASE_COLUMN">

        gid,name_py,name_ch,name_ft,pres_loc,type_py,type_ch,lev_rank,beg_yr,beg_rule,end_yr,end_rule,geo_src,compiler,gecomplr,checker,ent_date,beg_chg_ty,end_chg_ty,geom

    </sql>

    <select id="getCntyPoint" resultMap="geometryModelResult">

        SELECT

        <include refid="BASE_COLUMN"></include>

        FROM

        <include refid="CNTY_PTS"/>

        WHERE gid=#{gId} LIMIT 1

    </select>

    <select id="getprefPolygon" resultMap="geometryModelResult">

        SELECT

        <include refid="BASE_COLUMN"></include>

        FROM

        <include refid="PREF_PGN"/>

        WHERE gid=#{gId} LIMIT 1

    </select>



    <select id="getPrefPoint" resultMap="geometryModelResult">

        SELECT

        <include refid="BASE_COLUMN"></include>

        FROM

        <include refid="PREF_PTS"/>

        WHERE gid=#{gId} LIMIT 1

    </select>

</mapper>

 

 

 

四、localcache

直接查库较慢,所以我们把内容存在本地内存中,从内存中访问。

新建一个包:D:\gismap\java\gismap\src\main\java\com\history\gismap\localcache

在包下新建一个类:

D:\gismap\java\gismap\src\main\java\com\history\gismap\localcache\GeometryCache.java

这个类继承了InitializingBean,当程序启动的时候,数据就会加载。

程序中加入了map<>,按照表名区分cntypts、prefpts、prefpgn,每张表,每张表存成一个list,新建一个查询方法getDynastyGeometry,用表名和时间区间查询对象。

 

package com.history.gismap.localcache;

import
com.history.gismap.dao.MapDao;
import
com.history.gismap.model.GeometryModel;
import
lombok.extern.java.Log;
import
org.springframework.beans.factory.InitializingBean;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Service;

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

@Service
public class GeometryCache implements InitializingBean {
    Map<String
, List<GeometryModel>> historyGis =new HashMap<>();
   
@Autowired
   
private MapDao mapDao;
   
@Override
   
public void afterPropertiesSet() throws Exception {
        List<GeometryModel> cntyGeometry=
new ArrayList<>();
        int
i=1;
        while
(mapDao.getCntyPoint(i)!=null){
            cntyGeometry.add(
mapDao.getCntyPoint(i));
           
i++;
       
}
       
historyGis.put("cntypts",cntyGeometry);
       
List<GeometryModel>  prefPtsGeometry=new ArrayList<>();
       
i=1;
        while
(mapDao.getPrefPoint(i)!=null){
            prefPtsGeometry.add(
mapDao.getCntyPoint(i));
           
i++;
       
}
       
historyGis.put("prefpts",prefPtsGeometry);
       
List<GeometryModel> prefPgnGeometry=new ArrayList<>();
       
i=1;
        while
(mapDao.getprefPolygon(i)!=null){
            prefPgnGeometry.add(
mapDao.getprefPolygon(i));
           
i++;
       
}
       
historyGis.put("prefpgn",prefPgnGeometry);
   
}
   
public List<GeometryModel> getDynastyGeometry(String category,Integer start,Integer end){
        List<GeometryModel> result=
new ArrayList<>();
        for
(GeometryModel g:historyGis.get(category)) {
           
if((g.getBegYr()>=start && g.getBegYr()<=end)||(g.getEndYr()>=start&&g.getEndYr()<=end)){
                result.add(g)
;
           
}
        }
       
return result;
   
}
}

 

五.Service

D:\gismap\java\gismap\src\main\java\com\history\gismap\service\MapService.java

保证结构的规范性,service层还是要写下。

package com.history.gismap.service;
import
com.history.gismap.model.GeometryModel;
import
java.util.List;
public interface
MapService {
    List<GeometryModel>
getDynastyGeom(String category,Integer start,Integer end);
}

 

 

D:\gismap\java\gismap\src\main\java\com\history\gismap\service\impl\MapServiceImpl.java

impl

 

package com.history.gismap.service.impl;

import
com.history.gismap.dao.MapDao;
import
com.history.gismap.localcache.GeometryCache;
import
com.history.gismap.model.GeometryModel;
import
com.history.gismap.service.MapService;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Service;

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

@Service
public class MapServiceImpl implements MapService {
   
@Autowired
   
private GeometryCache geometryCache;
   
@Override
   
public List<GeometryModel> getDynastyGeom(String category,Integer start,Integer end){
       
return geometryCache.getDynastyGeometry(category,start,end);
   
}

}

 

 

六、controller

控制层。

D:\gismap\java\gismap\src\main\java\com\history\gismap\controller\MapController.java

用json跟前端交互数据,里面有一个方法geometryToJson,将geometry对象转成json,其实geometry.toString也可以将geometry转成String,但String有长度限制,转成json更安全些。

 

package com.history.gismap.controller;

import
com.alibaba.fastjson.JSONArray;
import
com.alibaba.fastjson.JSONObject;
import
com.alibaba.fastjson.JSONPath;
import
com.history.gismap.model.GeometryModel;
import
com.history.gismap.service.MapService;
import
com.vividsolutions.jts.geom.Coordinate;
import
com.vividsolutions.jts.geom.Geometry;
import
com.vividsolutions.jts.geom.GeometryFactory;
import
com.vividsolutions.jts.geom.Point;
import
com.vividsolutions.jts.io.ParseException;
import
com.vividsolutions.jts.io.WKTReader;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.*;

import
java.util.List;

@Controller
@RequestMapping
(value = "/history")
public class MapController {
   
@Autowired
   
private MapService mapService;
   
@ResponseBody
    @GetMapping
("/geometry")
   
public JSONObject getPoint(@RequestParam("category") String category,@RequestParam("start") Integer start,@RequestParam("end") Integer end){
        List<GeometryModel> result=
mapService.getDynastyGeom(category,start,end);
       
JSONObject jsonObject=new JSONObject();
       
jsonObject.put("number",result.size());
       
JSONArray jsonArray=new JSONArray();
        for
(GeometryModel g:result) {
            JSONObject geom=
new JSONObject();
           
geom.put("gid",g.getGId());
           
geom.put("namepy",g.getNamePy());
           
geom.put("namech",g.getNameCh());
           
geom.put("nameft",g.getNameFt());
           
geom.put("presloc",g.getPresLoc());
           
geom.put("typepy",g.getTypePy());
           
geom.put("typech",g.getTypeCh());
           
geom.put("levrank",g.getLevRank());
           
geom.put("begyr",g.getBegYr());
           
geom.put("begrule",g.getBegRule());
           
geom.put("endyr",g.getEndYr());
           
geom.put("endrule",g.getEndRule());
           
geom.put("geosrc",g.getGeoSrc());
           
geom.put("compiler",g.getCompiler());
           
geom.put("gecomplr",g.getGecomplr());
           
geom.put("checker",g.getChecker());
           
geom.put("entdate",g.getEntDate());
           
geom.put("begchgty",g.getBegChgTy());
           
geom.put("endchgty",g.getEndChgTy());
           
geom.put("geometry",geometryToJson(g.getGeometry()));
           
jsonArray.add(geom);
       
}
        jsonObject.put(
"list",jsonArray);
        return
jsonObject;
   
}
   
private JSONObject geometryToJson(Geometry geometry){
        JSONObject jsonObject=
new JSONObject();
       
jsonObject.put("type",geometry.getGeometryType());
       
JSONArray coorList=new JSONArray();
        for
(int i=0;i<geometry.getNumGeometries();i++){
            JSONArray coors=
new JSONArray();
           
Coordinate[] coordinates=geometry.getGeometryN(i).getCoordinates();
            for
(Coordinate c:coordinates) {
                JSONObject jsonObjectCoor=
new JSONObject();
               
jsonObjectCoor.put("lng",c.x);
               
jsonObjectCoor.put("lat",c.y);
               
coors.add(jsonObjectCoor);
           
}
            coorList.add(coors)
;
       
}
        jsonObject.put(
"coordinates",coorList);
        return
jsonObject;
   
}
}

 

 

七、测试:

启动程序。

D:\gismap\java\gismap\src\main\java\com\history\gismap\GismapApplication.java

启动后测试一下。

http://localhost:8080/history/geometry?category=prefpgn&start=-5000&end=-221

localhost:8080/history/geometry?category=prefpts&start=-5000&end=-221

localhost:8080/history/geometry?category=cntypts&start=-5000&end=-221

页面显示都是一坨的,chrome下载个JSONView吧。

按照方法参见:https://www.cnblogs.com/feiyu159/p/8968850.html

https://github.com/gildas-lormeau/JSONView-for-Chrome

安装完JSONView之后,页面长这样,比一坨好看多了。

从零开始,构建电子地图网站:0_9_web+InitializingBean启动加载本地缓存

 

整个工程已经完成的差不多了。

接着再建立一个分支,上传到git。

https://github.com/yimengyao13/gismap.git

分支:initbean

 

程序设计体系是数据、后端、前端分离,正常来说,后端要考虑到数据有问题、跟数据库连接有问题的情况是会存在的,而且为了后期维护,需要加上打印log日志、编写文档,不过说实话,日志是能看懂的,但自己的代码、自己写的文档,时间长了,真是一点也看不懂了。

 

这套程序,还少一些try-catch,log、注释等。