Link home to achieve the effect

Analysis of the

Map search function using point aggregation to achieve. The following is an example of the official website: lbs.qq.com/javascript_…

Lianjia’s house search is mainly divided into three layers. The first layer is the urban layer, such as Nanshan, Luohu, etc.; The second floor is the area, such as nantou, science park, etc. The third floor is the residential area.

Because layer 1 and Layer 2 don’t have that much data, both interfaces return all the data to the front end at once. However, the data volume of the third layer is very huge. What Lianjia takes is to return part of the data, and send the maximum longitude and latitude and minimum longitude and latitude displayed on the front page to the background, and then the background will return the filtered data to the front end. (Interface address you can use Chrome development tools for packet capture, here need to note that the link home interface uses the form of JSONP, so need to grab JS)

implementation

The first need to add Tencent map API, here is recommended to use the way of asynchronous loading. Because the project uses Vue to develop a single-page application, users may not enter the page of map search, so it is suggested to add Tencent Map API when opening the page of map search.

Asynchronous loading needs to avoid a reloading problem where the map API is the same no matter how many times the user opens the map to find a room. In order to reduce the code complexity, the singleton pattern is not used here. The specific code is as follows:

const TXMap = { map: undefined, GetApi (funName) {let script = document.createElement('script') script.type = 'text/javascript' script.src = `http://map.qq.com/api/js?v=2.exp&callback=${funName}` document.body.appendChild(script) } }Copy the code

SRC is the address of Tencent map API. SRC contains a callback parameter, indicating that funName will be called after js is loaded. After adding the map API, the Window object will have a Qm. maps object, which we can use to determine whether the API has been added to avoid adding the API repeatedly.

The next step is to implement the custom overlay method. Or refer to the official documentation: lbs.qq.com/javascript_…

Void lays: [], // void lays: [], // void lays: GetApi () {}, /* DrawOverlay (options) {let _this = this; This.sourcedata = options.data // Store the original data // Clear the original lays before drawing this.clearoverlays () // If the initMap method has been implemented, So we can just call, If (window.initmap === undefined) {window.initmap = function () {} // Draw overlay concrete // map API if not introduced call getApi Call initMap () window.qq === undefined? this.getApi('initMap') : window.initMap() } else { window.initMap() } }, Overlays () {let overlay while (overlay = this.overlays. Pop ()) {overlay. Onclick = null Overlay. ParentNode. RemoveChild (overlay) / / removing dom elements}}, / / beforeDestroy calls the Vue components, reset map, remove the time to listen, To avoid memory leaks clearMap () {this. The map = undefined if (this. The listener) {window. Qq. Maps. Event. RemoveListener (enclosing the listener)}}}Copy the code

This is where the shelf for the map search is set up, and then we’ll look at the implementation of the drawing overlay, initMap.

Window.initmap = function () {if (_this.map === undefined) { _this.map = new window.q.maps. map (document.getelementbyid (options.containerid), {// Initialize map center: New window. Qq. Maps. LatLng (options. The lat | | 22.702, the options. The LNG | | 114.09), / / initializes the zoom zoom: Options. Zoom | | 10, the minimum zoom level / / map minZoom: 10, / / disable zoom control zoomControl: false, / / disable the map type control mapTypeControl: False}) / / idle event, after the map zoom and pan _this trigger this event. The listener = window. Qq. Maps. The event. The addListener (_this. The map, "idle", GetBounds () let bounds = _this.map.getbounds () let zoom = _this.map.getzoom () // Call Vue The component's handler for idle events, options.callback && options.callback(bounds, Zoom)})} if (window.CustomOverlay === undefined) {window.CustomOverlay = function (lat, LNG, name, This. position = new window.q.maps. LatLng(lat, houseCount) {// Call the map API to calculate the location of the overlay. LNG) enclosing name = name / / area of enclosing houseCount = houseCount number} / / / / availability inheritance Overlay window. CustomOverlay. Prototype = new Overlay(); // Overlay(); // Overlay(); Style window. You can according to demand to draw CustomOverlay. Prototype. The construct = function () {let div = this. Div = Document.createelement ('div') div.className = 'my-overlay' // overlay className // HTML structure this.div.innerHTML = '<p Class = "count" > ${enclosing houseCount} < span > set < / span > < / p > < p class = "name" > ${this. The name} < / p > ` / / add the dom to the covering layer, OverlayMouseTarget sequence container 5, which contains transparent mouse corresponding elements, Used to receive mouse events Marker enclosing getPanes () overlayMouseTarget. The appendChild (div) / / div is added to the overlays, can be used to further processing Let center = this.position this.div.onclick = function () {// Zoom and pan the map after clicking let zoom = _this.map.getZoom() if (zoom < 13) { _this.map.setCenter(center) _this.map.setZoom(13) } else if (zoom >= 13 && zoom < 15) {_this.map.setCenter(center) _this.map.setzoom (15)}} // Implement the draw interface to draw DOM elements Window. CustomOverlay. Prototype. The draw = function () {let overlayProjection = this. GetProjection container () / / for covering the relative pixel coordinates of the let Pixel = overlayProjection. FromLatLngToDivPixel (enclosing the position) let divStyle = this. Div. The style / / adjust positioning according to DOM elements Divstyle. top = pixel.y -53 + 'px' divstyle. left = Pixel. x -30 + 'px'}} 0) { _this.sourceData.map(item => { let customOverlay = new window.CustomOverlay(item.latitude, item.longitude, item.name, item.house_count) customOverlay.setMap(_this.map) }) } }Copy the code

At this point, map search to draw overlay method encapsulation is complete, the next only need to expose TXMap, and then introduced in the Vue component, and then to the following method can be used

TXMap.drawOverlay({
  containerId: 'map-box',
  data: res.data
})
Copy the code

Implementation effect

This example uses the data of lianjia to make two layers, you can modify according to your own needs.

Project address: GitHub

Product dynamic

Tencent Location Service has launched 3D map API-JavaScript API GL.

Links to the 3D map API documentation for the above features: dot aggregation, custom coverings

The above content is reprinted from Front Develop’s article on How to find apartments on maps

Author: Front-end Develop

Links: juejin. Cn/post / 684490…

Source: Nuggets

Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.