Loading... <div class="tip inlineBlock warning"> 😂有点感兴趣,就顺便看看,图一乐。随缘学习更新。 </div> > 还是那句话,感谢黑马程序员。  # 地图概述 ## 地图技术 地图技术就是使用地图服务来完成各种业务的一种技术,如:基于经纬度定位、查询出行路线、导航、搜索附近的商场等。随着移动互联网的发展,移动终端可以更方便的获取用户的位置数据,地图技术的应用也得到了广泛的应用,如:网约车、智能穿戴、智能物流、智能景区、互联网房产、在线旅游、车用数据服务等。 ## 地图应用场景 ### 网约车服务 在网约车场景中实现准定位、导航、司乘同显、精准计费等核心需求。  ### 智能穿戴 实现智能穿戴设备定位、导航、轨迹追踪导等各种需求。  ### 智能物流 智能物流解决放中,地图技术支撑物流下单、分单、干线运输规划、轨迹管理等多类核心业务场景。  ### 智能景区 通过地图服务实现景区智能化、场景化,打造个性化智能景区。  ### 车联网 汽车企业通过地图数据和在线地图服务,实现车载导航、自动驾驶和手车互联等场景需求。  ## 国内常见地图 ### 百度地图 官网:https://map.baidu.com/ 开发平台:https://lbsyun.baidu.com/ ### 高德地图 官网:https://www.amap.com/ 开发平台:https://lbs.amap.com/ ### 腾讯地图 官网:https://map.qq.com/ 开放平台:https://lbs.qq.com/ ### 搜狗地图 官网:http://map.sogou.com/ 开放平台:http://map.sogou.com/api/  # 地图API与搜索 百度地图提供了各种平台的 SDK,地址:https://lbsyun.baidu.com/  ## JS API GL ### 创建浏览器端应用 登录账号,进入控制台,成为个人开发者,https://lbsyun.baidu.com/apiconsole/user/choose  应用管理 -> 我的应用 -> 创建应用 - 输入应用名称以及应用类型。 - 这里先选择浏览器端进行学习。 - 白名单中设置「*」号,说明没有域名限制。  创建完成,获取到「AK」  拉取项目,完成一些案例。  ### 创建地图 参考官方文档:https://lbsyun.baidu.com/index.php?title=jspopularGL/guide/show 注意,其中第二步「引入百度地图API文件」中的"您的密钥"需要修改为上面创建的应用「AK」 ```html <!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Baidu Map </title> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #container { height: 100% } </style> <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=您的密钥"></script> </head> <body> <div id="container"> </div> <script> var map = new BMapGL.Map("container"); // 创建地图实例 var point = new BMapGL.Point(116.404, 39.915); // 创建点坐标 map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别 map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 // map.setHeading(64.5); //设置地图旋转角度 // map.setTilt(73); //设置地图的倾斜角度 </script> </body> </html> ``` ### 添加控件 控件是负责与地图交互的 UI 元素,百度地图 API 支持比例尺、缩放、定位、城市选择列表、版权,以及自定义控件。文档:https://lbsyun.baidu.com/index.php?title=jspopularGL/guide/widget ```javascript var scaleCtrl = new BMapGL.ScaleControl(); // 添加比例尺控件 map.addControl(scaleCtrl); var zoomCtrl = new BMapGL.ZoomControl(); // 添加缩放控件 map.addControl(zoomCtrl); var cityCtrl = new BMapGL.CityListControl(); // 添加城市列表控件 map.addControl(cityCtrl); var locationCtrl = new BMapGL.LocationControl(); // 添加定位控件 map.addControl(locationCtrl); ``` ### 添加覆盖物 所有叠加或覆盖到地图的内容,我们统称为地图覆盖物。覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的移动。目前 JSAPI GL 版支持的覆盖物以基本图形为主。文档:https://lbsyun.baidu.com/index.php?title=jspopularGL/guide/addOverlay 可以使用 map.addOverlay 方法向地图添加覆盖物,使用 map.removeOverlay 方法移除覆盖物。 | **覆盖物** | **类名** | **说明** | | ---------- | -------- | ---------------------------------- | | 抽象基类 | Overlay | 所有的覆盖物均继承此类的方法 | | 点 | Marker | 表示地图上的点,可自定义标注的图标 | | 折线 | Polyline | 表示地图上的折线 | | 多边形 | Polygon | 表示地图上的多边形 | | 圆 | Circle | 表示地图上的圆 | **添加点标注** ```javascript var point = new BMapGL.Point(116.404, 39.915); var marker = new BMapGL.Marker(point); // 创建标注 map.addOverlay(marker); // 将标注添加到地图中 // 监听标注点 marker.addEventListener("click", function () { alert("您点击了该位置"); }); ``` ### 地图事件 百度地图 API 中的大部分对象都含有 `addEventListener` 方法,您可以通过该方法来监听对象事件。例如,BMapGL.Map 包含 click、dblclick 等事件。在特定环境下这些事件会被触发,同时监听函数会得到相应的事件参数 e,比如当用户点击地图时,e 参数会包含鼠标所对应的地理位置 latlng ```javascript map.addEventListener('click', handleClick); function handleClick(e) { alert('点击的经纬度:' + e.latlng.lng + ', ' + e.latlng.lat); var mercator = map.lnglatToMercator(e.latlng.lng, e.latlng.lat); alert('点的墨卡托坐标:' + mercator[0] + ', ' + mercator[1]); } ``` ### 地图样式 百度地图支持设置地图样式,比如将地图设置为地球模式,文档:https://lbsyun.baidu.com/index.php?title=jspopularGL/guide/maptype ```javascript map.setMapType(BMAP_EARTH_MAP); // 设置地图类型为地球模式 ``` ### 地图检索 这一块内容直接看百度地图案例即可:https://lbsyun.baidu.com/jsdemo.htm#localSearchKey ```javascript var local = new BMapGL.LocalSearch(map, { renderOptions:{map: map} }); local.search("景点"); ``` ### 数据可视化 MapVGL,是一款基于 WebGL 的地理信息可视化库,可以用来展示大量基于 3D 的地理信息点线面数据。 文档:https://lbsyun.baidu.com/solutions/mapvdata  ## Web服务API 为开发者提供 http/https 接口,即开发者通过 http/https 形式发起检索请求,获取返回 json 或 xml 格式的检索数据。用户可以基于此开发 JavaScript、C#、C++、Java 等语言的地图应用。文档地址: https://lbsyun.baidu.com/index.php?title=webapi  ### 创建服务端应用 输入应用名称以及应用类型,这里选择服务器端进行学习。 IP 白名单中设置"0.0.0.0/0"号,说明对 IP 地址没有限制。  ### 坐标转换 目前中国主要有以下三种坐标系: WGS84:为一种大地坐标系,也是目前广泛使用的 GPS 全球卫星定位系统使用的坐标系。 GCJ02:是由中国国家测绘局制订的地理信息系统的坐标系统,由 WGS84 坐标系经加密后的坐标系。 BD09:百度坐标系,在 GCJ02 坐标系基础上再次加密,其中 bd09ll 表示百度经纬度坐标,bd09mc 表示百度墨卡托米制坐标。 Web api 中提供了将非百度坐标转换成百度坐标体系的接口服务。 官网文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition > 用户可通过该服务,实现非百度坐标系(GPS标准坐标、amap地图坐标、tencent地图坐标、mapbar地图坐标等)到百度坐标系的转换。 比较简单,按照文档读懂即可。 ```java @Test public void test1(){ String url = "https://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak={}"; url = StrUtil.format(url, ak); String body = HttpRequest.get(url).execute().body(); System.out.println(body); } ``` ### IP地位 普通 IP 定位是一套以 HTTP/HTTPS 形式提供的轻量级定位接口,用户可以通过该服务,根据 IP 定位来获取大致位置。**适用于对定位精度要求不高的 IP 请求定位的应用。** 文档:https://lbsyun.baidu.com/index.php?title=webapi/ip-api  ```java @Test public void test2(){ String url = "http://api.map.baidu.com/location/ip?ak={}&ip={}&coor=bd09ll"; url = StrUtil.format(url,ak,"140.206.149.83"); String body = HttpRequest.get(url).execute().body(); JSONObject object = JSONUtil.parseObj(body); System.out.println(object); } ``` ### 地点输入提示 用户可通过该服务,匹配用户输入关键词的地点推荐列表。匹配用户输入内容,提供输入提示功能。常与[地点检索](http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi)服务搭配使用。也可作为轻量级地点检索服务单独使用(不支持复杂检索场景)。 文档:https://lbsyun.baidu.com/index.php?title=webapi/place-suggestion-api  ```java @Test public void test3(){ String url = "https://api.map.baidu.com/place/v2/suggestion?query={}®ion=广州&city_limit=true&output=json&ak={}"; url = StrUtil.format(url,"广财",ak); String body = HttpRequest.get(url).execute().body(); JSONObject object = JSONUtil.parseObj(body); System.out.println(object); } ``` ### 路线规划 路线规划服务(又名Direction API)是一套 REST 风格的 Web 服务 API,以 HTTP/HTTPS 形式提供了路线规划服务。目前,Direction API 支持公交、骑行、驾车路线规划,Direction API 支持中国大陆地区。 文档:https://lbsyun.baidu.com/index.php?title=webapi/direction-api-v2 以「驾车路线规划」为例:  ```java @Test public void test4(){ String url = "https://api.map.baidu.com/direction/v2/driving?origin=40.01116,116.339303&destination=39.936404,116.452562&ak={}"; url = StrUtil.format(url,ak); String body = HttpRequest.get(url).execute().body(); JSONObject object = JSONUtil.parseObj(body); System.out.println(object); } ``` ## 地图导航 ### BMapGLLib lBMapGLLib 是基于百度地图 JS API GL版的 JavaScript 开源工具库。代码地址:https://github.com/huiyan-fe/BMapGLLib  ### 静态页面 静态页面实现的基本思路步骤: 1.加载百度地图,需要开启滚轮功能以及显示比例尺; 引入必要的资源,注意不要挂「梯」。 ```javascript <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=yQaLjgCSeyRSBLBwjtKK73L4IBlRTVZk"></script> <script type="text/javascript" src="jquery-3.6.0.min.js"></script> <script type="text/javascript" src="https://mapopen.bj.bcebos.com/github/BMapGLLib/RichMarker/src/RichMarker.min.js"></script> ``` 2.给地图添加拖拽、缩放事件,来控制覆盖物的显示; 支持的事件,官网文档:https://mapopen-pub-jsapi.bj.bcebos.com/jsapi/reference/jsapi_webgl_1_0.html 我们在拖动和缩放开始时,清除覆盖物;在拖动和缩放结束后以及初始状态时,显示覆盖物。 ```JavaScript // 拖动开始事件 map.addEventListener("dragstart", () => { clearMapMarker(map) }); // 拖动结束事件 map.addEventListener("dragend", () => { showInfo(map) }); // 缩放开始事件 map.addEventListener("zoomstart", () => { clearMapMarker(map) }); // 缩放结束事件 map.addEventListener("zoomend", () => { showInfo(map) }); // 初始显示数据 showInfo(map); ``` 3.通过百度地图的 BMapGLLib 工具库中的 RichMarker(富标注),显示自定义覆盖物; 比较简单,需要了解 RichMarker 的使用方法,官方案例:https://github.com/huiyan-fe/BMapGLLib/blob/master/RichMarker/examples/RichMarker.html ```javascript function clearMapMarker(map) { let markers = map.getOverlays(); for (let marker of markers) { map.removeOverlay(marker); } } function showMapMarker(data, map) { for (let vo of data) { let html = "<div class=\"district\">" + vo.name + "<span>" + vo.price + "万</span><i>" + vo.total + "套</i></div>"; let marker = new BMapGLLib.RichMarker(html, new BMapGL.Point(vo.longitude, vo.latitude)); map.addOverlay(marker); } } ``` 4.通过 Ajax 异步加载数据,动态生成覆盖物,在地图上展现出来。 这一步还需要考虑地图的可视范围,只搜索显示出可视范围内的数据展示即可。 ```javascript function showInfo(map) { // 可视范围矩形坐标, // 其中sw表示矩形区域的西南角,ne表示矩形区域的东北角 // 相当于拿到地图在可视区域的范围 // 用于获取范围内的有效数据 let bound = map.getBounds(); // 缩放级别 let zoom = map.getZoom(); console.log(bound); // todo Ajax 请求数据 // --- // 测试数据 let data = [{ "name": "徐汇", "price": "1028.43", "total": "6584", "longitude": 121.43676, "latitude": 31.18831 }, { "name": "黄浦", "price": "1016.19", "total": "7374", "longitude": 121.49295, "latitude": 31.22337 }, { "name": "长宁", "price": "1008.34", "total": "4380", "longitude": 121.42462, "latitude": 31.22036 }, { "name": "静安", "price": "1005.34", "total": "8077", "longitude": 121.4444, "latitude": 31.22884 }, { "name": "普陀", "price": "1026.14", "total": "5176", "longitude": 121.39703, "latitude": 31.24951 }, { "name": "金山", "price": "1099.67", "total": "6", "longitude": 121.34164, "latitude": 30.74163 }, { "name": "松江", "price": "1017.71", "total": "14", "longitude": 121.22879, "latitude": 31.03222 }, { "name": "青浦", "price": "1038.11", "total": "751", "longitude": 121.12417, "latitude": 31.14974 }, { "name": "奉贤", "price": "1108.63", "total": "35", "longitude": 121.47412, "latitude": 30.9179 }, { "name": "浦东", "price": "1030.22", "total": "8294", "longitude": 121.5447, "latitude": 31.22249 }, { "name": "嘉定", "price": "1041.45", "total": "1620", "longitude": 121.2655, "latitude": 31.37473 }, { "name": "宝山", "price": "1050.65", "total": "102", "longitude": 121.4891, "latitude": 31.4045 }, { "name": "闵行", "price": "1027.15", "total": "941", "longitude": 121.38162, "latitude": 31.11246 }, { "name": "杨浦", "price": "1007.78", "total": "2747", "longitude": 121.526, "latitude": 31.2595 }, { "name": "虹口", "price": "1025.81", "total": "4187", "longitude": 121.48162, "latitude": 31.27788 }]; showMapMarker(data, map); } ``` ### MongoDB环境 直接使用 Docker 搭建 MongoDB 环境比较简单。 ```shell #拉取镜像 docker pull mongo:4.0.3 #创建容器 docker create --name mongodb-server -p 27017:27017 -v mongodb-data:/data/db mongo:4.0.3 --auth #启动容器 docker start mongodb-server #进入容器 docker exec -it mongodb-server /bin/bash #进入admin数据库 mongo use admin #添加管理员,其拥有管理用户和角色的权限 db.createUser({ user: 'root', pwd: '123456', roles: [ { role: "root", db: "admin" } ] }) #退出后进行认证 exit #进行认证 mongo -u "root" -p "123456" --authenticationDatabase "admin" #通过admin添加普通用户 use admin db.createUser({ user: 'house', pwd: '123456', roles: [ { role: "readWrite", db: "house" } ] }); #退出后进行认证 exit #通过house用户登录进行测试 mongo -u "house" -p "123456" --authenticationDatabase "admin" #发现可以正常进入控制台进行操作 ``` 在后端 application.properties 配置文件中配置 MongoDB ```properties #springboot MongoDB配置 spring.data.mongodb.username=house spring.data.mongodb.password=123456 spring.data.mongodb.authentication-database=admin spring.data.mongodb.database=house spring.data.mongodb.port=27017 spring.data.mongodb.host=192.168.211.129 spring.data.mongodb.auto-index-creation=true ``` 使用 Navicat 连接数据库,导入数据  ### MongoDB聚合 MongoDB 的聚合操作是以管道的形式完成的,在一个管道处理完毕后将结果传递给下一个管道处理。 常用的聚合操作有: | 表达式 | 作用 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | $project | 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。 | | $match | 用于过滤数据,只输出符合条件的文档。$match 使用 MongoDB 的标准查询操作。 | | | $limit | 用来限制 MongoDB 聚合管道返回的文档数。 | | $skip | 在聚合管道中跳过指定数量的文档,并返回余下的文档。 | | $unwind | 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。 | | $group | 将集合中的文档分组,可用于统计结果。 | | $sort | 将输入文档排序后输出。 | | $geoNear | 输出接近某一地理位置的有序文档。 | **MongoDB 聚合操作符** 主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。 类似 SQL 语句中的 `count(*)` 这类操作,常用操作如下: | 表达式 | 描述 | 实例 | | --------- | ---------------------------------------------- | ------------------------------------------------------------ | | $sum | 计算总和。 | `db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])` | | $avg | 计算平均值。 | `db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])` | | $min | 获取集合中所有文档对应值得最小值。 | `db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])` | | $max | 获取集合中所有文档对应值得最大值。 | `db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])` | | $push | 在结果文档中插入值到一个数组中。 | `db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])` | | $addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | `db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])` | | $first | 根据资源文档的排序获取第一个文档数据。 | `db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])` | | $last | 根据资源文档的排序获取最后一个文档数据。 | `db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])` | ### 构造数据 按照行政区查询每个区的房源数量以及平均价格。 ```sql db.tb_house.aggregate([{ $group: { _id: "$districtCode", price: { $avg: "$price" }, total: { $sum: 1 } } }]) ```  ### 后端实现搜索 ```java @RestController @RequestMapping("/house/search") public class HouseSearchController { @Autowired private HouseSearchService houseSearchService; /** * 地图找房搜索服务 * * @param maxLongitude 最大经度 * @param minLongitude 最小经度 * @param maxLatitude 最大纬度 * @param minLatitude 最小纬度 * @param zoom 地图缩放比例值 */ @GetMapping public List<HouseResultVo> search(@RequestParam("maxLongitude") Double maxLongitude, @RequestParam("minLongitude") Double minLongitude, @RequestParam("maxLatitude") Double maxLatitude, @RequestParam("minLatitude") Double minLatitude, @RequestParam("zoom") Double zoom) { return houseSearchService.search(maxLongitude, minLongitude, maxLatitude, minLatitude, zoom); } } ``` 业务不难,较繁琐,通过不同的地图范围来执行不同的查询操作。 吐槽:单词拼错,查询为空,找了一小时都找不出来,最后重新写一遍才醒悟。服了。 ```java package com.xn2001.baidumap.search.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.NumberUtil; import com.xn2001.baidumap.pojo.BusinessCircle; import com.xn2001.baidumap.pojo.Community; import com.xn2001.baidumap.pojo.District; import com.xn2001.baidumap.pojo.House; import com.xn2001.baidumap.search.HouseSearchService; import com.xn2001.baidumap.vo.HouseResultVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.geo.Box; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.*; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @author 乐心湖 * @version 1.0 * @date 2022/7/15 4:10 */ @Service public class HouseSearchServiceImpl implements HouseSearchService { @Autowired private MongoTemplate mongoTemplate; public List<HouseResultVo> search(Double maxLongitude, Double minLongitude, Double maxLatitude, Double minLatitude, Double zoom) { //聚合查询条件 List<AggregationOperation> aggregationOperations = new ArrayList<>(); //可视范围内搜索 Box box = new Box(new double[]{maxLongitude, maxLatitude}, new double[]{minLongitude, minLatitude}); MatchOperation location = Aggregation.match(Criteria.where("location").within(box)); aggregationOperations.add(location); //分组信息 GroupOperation groupOperation; int type; //根据地图缩放比例分组 if (zoom < 13.5) { //2公里以上,按照行政区分组 groupOperation = Aggregation.group("districtCode"); type = 1; } else if (zoom < 15.5) { //200米以上,按照商圈分组 groupOperation = Aggregation.group("businessCircleCode"); type = 2; } else { //200米以下,按照小区分组 groupOperation = Aggregation.group("communityId"); type = 3; } //注意这里一定要覆盖 groupOperation = groupOperation.count().as("total") .avg("price").as("price"); aggregationOperations.add(groupOperation); //生成最终的聚合条件 Aggregation aggregation = Aggregation.newAggregation(aggregationOperations); //执行聚合查询 AggregationResults<HouseResultVo> aggregate = mongoTemplate.aggregate(aggregation, House.class, HouseResultVo.class); //拿到匹配结果 List<HouseResultVo> houseResultVos = aggregate.getMappedResults(); if (CollUtil.isEmpty(houseResultVos)) { return Collections.emptyList(); } switch (type){ case 1: //查询行政区数据 for (HouseResultVo houseResultVo : houseResultVos) { District district = this.queryDistrictByCode(Convert.toInt(houseResultVo.getCode())); houseResultVo.setName(district.getName()); houseResultVo.setLongitude(district.getLocation().getX()); houseResultVo.setLatitude(district.getLocation().getY()); houseResultVo.setPrice(NumberUtil.roundStr(houseResultVo.getPrice(),2)); } break; case 2: //查询商圈数据 for (HouseResultVo houseResultVo : houseResultVos) { BusinessCircle businessCircle = this.queryBusinessCircleByCode(Convert.toInt(houseResultVo.getCode())); houseResultVo.setName(businessCircle.getName()); houseResultVo.setLongitude(businessCircle.getLocation().getX()); houseResultVo.setLatitude(businessCircle.getLocation().getY()); //价格保留2位小数 houseResultVo.setPrice(NumberUtil.roundStr(houseResultVo.getPrice(), 2)); } break; case 3: //查询小区数据 for (HouseResultVo houseResultVo : houseResultVos) { Community community = this.queryCommunityById(houseResultVo.getCode()); houseResultVo.setName(community.getName()); houseResultVo.setLongitude(community.getLocation().getX()); houseResultVo.setLatitude(community.getLocation().getY()); //价格保留2位小数 houseResultVo.setPrice(NumberUtil.roundStr(houseResultVo.getPrice(), 2)); } break; default: return Collections.emptyList(); } return houseResultVos; } /** * 根据code查询行政区数据 * @return */ private District queryDistrictByCode(Integer code) { Query query = Query.query(Criteria.where("code").is(code)); return mongoTemplate.findOne(query, District.class); } /** * 根据code查询商圈数据 * @return */ private BusinessCircle queryBusinessCircleByCode(Integer code) { Query query = Query.query(Criteria.where("code").is(code)); return mongoTemplate.findOne(query, BusinessCircle.class); } /** * 根据code查询小区数据 * @return */ private Community queryCommunityById(Object id) { return mongoTemplate.findById(id, Community.class); } } ``` 前端 Ajax 请求 ```javascript $.ajax({ url: "/house/search", data: { maxLongitude: bound.ne.lng, minLongitude: bound.sw.lng, maxLatitude: bound.ne.lat, minLatitude: bound.sw.lat, zoom: zoom }, success: function (data) { showMapMarker(data, map); } }) ```  # 健康运动轨迹 。。。 Last modification:July 16, 2022 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 如果觉得我的文章对你有用,请随意赞赏
5 comments
j ava真头大啊
java 真头大啊
Java真头大
adfs
Java真头大啊