环境准备
开发工具:IntellJ IDEA
数据库:MySQL 5.7.22
技术框架:Spring Boot(2.2.0.RELEASE) + Mybatis Plus(3.2.0)
第三方地图:高德地图官方API
构建项目
添加依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.0.RELEASEversion>
<relativePath/>
parent>
<groupId>com.gemgroupId>
<artifactId>map-appartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>map-appname>
<description>map-app project for Spring Bootdescription>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>11java.version>
<mybatis.plus.version>3.2.0mybatis.plus.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>${mybatis.plus.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.15version>
dependency>
<dependency>
<groupId>net.sf.json-libgroupId>
<artifactId>json-libartifactId>
<version>2.4version>
<classifier>jdk15classifier>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>org.junit.vintagegroupId>
<artifactId>junit-vintage-engineartifactId>
exclusion>
exclusions>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
配置yml文件
#服务器配置
server:
port: 9000
# servlet:
# context-path: /map-app
#数据库相关配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/map_hotel?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
#mybatis plus配置
mybatis-plus:
# 如果是放在src/main/java目录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml
# 如果是放在resource目录 classpath:/mapper/*Mapper.xml
# mapper-locations: classpath*:mapper/*Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.gem.entity
global-config:
# #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: 0
# #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: 0
# #驼峰下划线转换
# db-column-underline: true
# #mp2.3+ 全局表前缀 mp_
# #table-prefix: mp_
# #刷新mapper 调试神器
# #refresh-mapper: true
# #数据库大写下划线转换
# #capital-mode: true
# # Sequence序列接口实现类配置
# key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
# #逻辑删除配置(下面3个配置)
logic-delete-value: 1
logic-not-delete-value: 0
# sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
# #自定义填充策略接口实现
# meta-object-handler: com.baomidou.springboot.MyMetaObjectHandler
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# #配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
# map-underscore-to-camel-case: true
cache-enabled: true
# #配置JdbcTypeForNull, oracle数据库必须配置
# jdbc-type-for-null: 'null'
项目结构
准备数据
为了首页地图的加载效果,提前建表准备数据,
开发Controller
定义IndexController.java类,并创建映射方法,示例代码如下:
@Controller
@RequestMapping("/home")
public class IndexController {
@RequestMapping("/index")
public String index(Model model) {
Hotel hotel = new Hotel();
List<Hotel> hotelList = hotel.selectList(new QueryWrapper<>());
List list = new ArrayList();
for (Hotel ho: hotelList) {
JSONObject object = new JSONObject();
BigDecimal[] point = {ho.getLongitude(),ho.getLatitude()};
object.put("position", point);
object.put("name", ho.getName());
object.put("img", ho.getImg());
object.put("detailAddress", ho.getDetailAddress());
list.add(object);
}
model.addAttribute("hotelList",list);
model.addAttribute("urlFlag","index");
return "index";
}
}
定义视图
页面结构
<body>
<div th:include="common/header :: html">div>
<div id="container">div>
body>
导航部分以外部文件引入的方式处理。
公共头部结构
部分核心代码如下:
<div class="container boxx">
<br><br>
<div class="row">
<div class="col-md-3">
<img th:src="@{/image/logo.png}" width="200px" style="margin-top: -10px" />
div>
<div class="col-md-7 col-md-offset-1">
<ul class="nav">
<li class="navli">
<a th:class="${urlFlag eq 'index' ? 'active-a' : ''}" th:href="@{/home/index}" class="hvr-shutter-out-vertical">首页a>
li>
<li class="navli">
<a th:class="${urlFlag eq 'hotel' ? 'active-a' : ''}" href="javascript:;" onclick="managerHotel()" class="hvr-shutter-out-vertical">管理酒店a>
li>
ul>
div>
div>
<br>
div>
引入地图js文件
<link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css" />
<script src="https://webapi.amap.com/maps?v=1.4.10&key=ccc557b111dd155750089e029fe3126e&plugin=AMap.AdvancedInfoWindow"></script>
地图样式文件:main1119.css
引入脚本:其中key=ccc557b111dd155750089e029fe3126e,该key值开发时需要自行申请
创建地图
(1)在js中创建地图对象,并放置到页面
<script type="text/javascript" th:inline="javascript">
var map = new AMap.Map("container", {resizeEnable: true});
</script>
AMap.Map对象中的参数container即为页面元素的id值,可以自行修改。
(2)设置定位
将后台返回的酒店集合对象在地图中以定位的方式显示。使用map对象的插件设置,示例代码:
//定位
map.plugin('AMap.Geolocation', function() {
geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:无穷大
maximumAge: 0, //定位结果缓存0毫秒,默认:0
convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, //显示定位按钮,默认:true
buttonPosition: 'LB', //定位按钮停靠位置,默认:'LB',左下角
buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true
showCircle: true, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy: false, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
radius: 1000 //范围,默认:500
});
map.addControl(geolocation);
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, 'complete', onComplete); //返回定位信息
AMap.event.addListener(geolocation, 'error', onError); //返回定位出错信息
});
ips: 该段配置有官方文档提供,需要设置的参数可自行调整。
在上段代码中,这行代码AMap.event.addListener(geolocation, ‘complete’, onComplete);设置定位成功的回调。
(3)解析定位
定义onComplete回调函数,示例代码:
//解析定位结果
function onComplete(data) {
if(data.status == 1) {
$("#addressInput").val(data.formattedAddress);
sessionStorage.setItem("dingWei-lng", data.position.getLng());
sessionStorage.setItem("dingWei-lat", data.position.getLat());
}
}
(4)获取定位数据
定义变量接收后台的酒店集合数据,示例代码:
var markers = hotelList;
其中hotelList可使用行内表达式提取request对象中的值。示例代码:
<script th:inline="javascript">
/*
var contextPath = [[${#request.getContextPath()}]]; //获取当前应用路径
var hotelList=[[${hotelList}]];
/*]]>*/
</script>
(5)创建定位信息
将集合中对象的经纬度等信息绑定到定位锚点上,示例代码:
for(var i = 0, marker; i < markers.length; i++) {
var marker = new AMap.Marker({
position: markers[i].position,
icon: startIcon,
map: map
});
marker.content = ''+markers[i].name+'' +
'+ contextPath + '/image/hotel/'+ markers[i].img +'">' +
'酒店地址:'+markers[i].detailAddress+'
' +
'点击查看酒店详情';
marker.on('click', markerClick);
marker.emit('click', {target: marker});
}
(5)自定义定位小图标
为了更好的展示效果,可以为定位锚点自定义icon。示例代码:
var startIcon = new AMap.Icon({
// 图标尺寸
size: new AMap.Size(30, 34),
// 图标的取图地址
image: contextPath + '/image/marker.png',
// 图标所用图片大小
imageSize: new AMap.Size(25, 34),
});
(6)添加点击事件
如果点击不同的锚点时,弹窗显示当前锚点的详细详细。此时可以为锚点添加点击事件,示例代码:
function markerClick(e) {
infoWindow.setContent(e.target.content);
infoWindow.open(map, e.target.getPosition());
}
(7)完整js代码
<script th:inline="javascript">
/*
var contextPath = [[${#request.getContextPath()}]]; //获取当前应用路径
var hotelList=[[${hotelList}]];
/*]]>*/
</script>
<script type="text/javascript" th:inline="javascript">
var map = new AMap.Map("container", {resizeEnable: true});
/**
* 浏览器定位
*/
//定位
map.plugin('AMap.Geolocation', function() {
geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:无穷大
maximumAge: 0, //定位结果缓存0毫秒,默认:0
convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, //显示定位按钮,默认:true
buttonPosition: 'LB', //定位按钮停靠位置,默认:'LB',左下角
buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true
showCircle: true, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy: false, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
radius: 1000 //范围,默认:500
});
map.addControl(geolocation);
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, 'complete', onComplete); //返回定位信息
AMap.event.addListener(geolocation, 'error', onError); //返回定位出错信息
});
//解析定位结果
function onComplete(data) {
if(data.status == 1) {
$("#addressInput").val(data.formattedAddress);
sessionStorage.setItem("dingWei-lng", data.position.getLng());
sessionStorage.setItem("dingWei-lat", data.position.getLat());
}
}
var markers = hotelList;
var infoWindow = new AMap.AdvancedInfoWindow({offset: new AMap.Pixel(0, -30)});
// 创建一个 Icon
var startIcon = new AMap.Icon({
// 图标尺寸
size: new AMap.Size(30, 34),
// 图标的取图地址
image: contextPath + '/image/marker.png',
// 图标所用图片大小
imageSize: new AMap.Size(25, 34),
});
for(var i = 0, marker; i < markers.length; i++) {
var marker = new AMap.Marker({
position: markers[i].position,
icon: startIcon,
map: map
});
marker.content = ''+markers[i].name+'' +
'+ contextPath + '/image/hotel/'+ markers[i].img +'">' +
'酒店地址:'+markers[i].detailAddress+'
' +
'点击查看酒店详情';
marker.on('click', markerClick);
marker.emit('click', {target: marker});
}
function markerClick(e) {
infoWindow.setContent(e.target.content);
infoWindow.open(map, e.target.getPosition());
}
map.setFitView();
</script>