preface

Based on MPVUE framework, this paper discusses the development of map-based applets. The original author made use of the ability of MPvue + Tencent map to make a small program of metro line planning, which mainly provides the subway line network map and tourism introduction of major cities in the world, among which domestic cities support to view the map and route planning.

At present, Tencent location service also launched a route planning plug-in, metro map plug-in, to achieve a more simple and convenient, interested can click to view.

Run a screenshot

Mpvue introduction and project construction

Mpvue = miniProgram + VUE framework, in plain English, is to develop small programs with vUE framework. Mpvue was recently upgraded to version 2.x, which supports wechat, Alipay, Baidu and Toutiao. Compared with the traditional way, MPVUE development has the following advantages:

Radical componentized development capabilities: improved code reuse

  • Complete vue.js development experience

  • Convenient Vuex data management solution: Easy to build complex applications

  • Quick WebPack build mechanism: custom build strategy, hotReload during development

  • Support for using NPM external dependencies

  • Use vue-CLI command line tool vue.js to quickly initialize the project

  • H5 code conversion ability to compile into small program object code

In terms of personal experience, it is still very smooth, traditional Web application development seamlessly switch to small program development, basically zero threshold. Note the limitations of applets and their differences from Vue:

  • Applet style layout using relative pixels RPX

  • Part of the CSS selector doesn’t support, currently only support # id. | class | tag | tag, the tag | : : after: : before, so it is important to pay special attention to

  • For details, see mpvue.com/mpvue/#_3. Currently, there are many bugs in mpVue. For example, when a small application page is unloaded, the vue instance is not destroyed. The state must be manually reset at unLoad, etc

  • Mpvue encapsulates small program data objects, usually starting with $mp, such as event.$mp.detail.target

  • Applets are different from VUE components. Do not assume that all vUE components will work, such as slot, asynchronous components, and so on

  • Vue Store and WX localStorage should not be confused, choose different storage methods according to different needs

  • Don’t use VUE routing, use applets native navigation mechanism

We then set up the development environment and the MPvue scaffolding is out of the box:

$NPM install --global [email protected] # Create a new project based on the mpvue-quickStart template $CD my-project $NPM install $NPM run devCopy the code

Then, improve the file structure, add config, Store, mixins and other modules, as shown in the figure:

App. json is a special file for small programs, also need to improve:

{ "pages": [ "pages/citylist/main", "pages/citydetail/main" ], "permission": { "scope.userLocation": { "desc": "Your location information will be used in small program interface to show the effect of"}}, "window" : {" backgroundTextStyle ":" light ", "navigationBarBackgroundColor" : "#eee", "navigationBarTitleText": "navigationBartitleStyle ": "black"}Copy the code

Then you can have fun writing Vue code, click a page, click another page, component, store, data-driven, whatever you like, it has.

Tencent map + small program

Focus on map access, Tencent map provides two docking entrance to small program, 1 is personalized map display, 2 is dedicated SDK, the two together to improve the map ecology of small program.

1. Personality map display requires the developer to register and apply for the developer key, bind the small program in the management background, and then set the style of personality map to use:

<map id="citymap" name="citymap" :longitude="lng" :latitude="lat" :polyline="polyline" :markers="markers" scale="12" :subkey="YOUR_OWN_QQMAP_KEY" show-location show-compass enable-rotate style="width: 100%; height: 100%;" <button class=" explored-btn "type="primary" @tap="exploreCity"> </button> </cover-view> </map>Copy the code

Map is the native component of the applet. The native component has the highest hierarchy outside the WebView rendering process, so no matter how much z-index is set to other components in the page, it cannot be overlaid on the native component. To put it plainly, the native component is provided by the wechat client, which does not belong to the built-in browser. Therefore, the small program provides cover-view and cover-image components specially, which can be covered on some of the native components. These two components are also native components, but the usage restrictions are different from the other native components.

I lost a lot of time because of this pit, sometimes the development tools can be used, but on the real machine components are completely messed up, so it is still a real machine debugging. For native components, don’t use too complex CSS, many of its CSS properties don’t support well.

Scale is used to draw lines on a map, polyline is used to mark points, show-location is used to show the user’s location, and show-compass is used to show the north point.

2. Dedicated SDK currently provides these capabilities:

  • Search (options:Object) Location search, search for nearby POIS, such as “hotel”, “dining”, “entertainment”, “school”, etc

  • GetSuggestion (options:Object) is used to get the completion and prompt for input keywords to help users quickly enter keywords

  • ReverseGeocoder (Options :Object) provides conversion from coordinate to literal description of coordinate location. The input coordinates return geolocation information and a list of nearby POIS

  • Geocoder (Options :Object) provides the conversion from address description to the coordinates of the position, as opposed to the process of reverse address resolution

  • Direction (Options :Object) provides driving, walking, cycling, bus route planning capability

  • GetCityList () gets a list of cities across the country

  • GetDistrictByCityId (options:Object) Returns the district under the city using the city ID

  • CalculateDistance (options:Object) Calculates walking and driving distance from one point to multiple points

Let’s take public transport route planning as an example (the following code has been simplified) :

First, initialize the map SDK object

import config from '@/config' import QQMapWX from '.. /.. / assets/lib/qqmap - wx - JSSDK. Js' / / here using the uncompressed version of the code const QQMapSDK = new QQMapWX ({key: config qqMapKey | | '})Copy the code

The second step, to obtain the starting and ending coordinates, and route query

/ / coordinates from the previous query incoming, coordinates of floating point Numbers, can get this. Through the geocoder interface fromLocation = {latitude: + query from split (', ') [0] | | 1, longitude: +query.from.split(',')[1] || -1 } this.toLocation = { latitude: +query.to.split(',')[0] || -1, longitude: + query. To. The split (', ') [1] | | - 1} / / query route map queryMapRoutine () {QQMapSDK. Direction ({mode: 'transit', // 'transit' // From: this.fromLocation, to: this.toLocation, success: (res) => {console.log(' route planning result ', res); let routes = res.result.routes; This.routes = routes.map(r => {this.routes = routes.map) Return this.parseroute (r)}) console.log('parsed routes', this.routes)}})}Copy the code

The third step, route analysis, generate route description, etc

// Parse route, including distance, time, description, route, ParseRoute (route) {let result = {} // Start time result.setoutTime = formatTime(new Date()) result.distance = route.distance < 1000 ? ${route.distance} m ':' ${(route.distance / 1000).tofixed (2)} km 'result.duration = route.duration < 60? '${route.duration} minutes' : Duration % 60} min 'result.desc = [] ${route.duration % 60} min' result.desc = [] Steps. ForEach (step => {// if (step.mode == 'WALKING' && step.distance > 0) {// Result.desc.push (' walk ${step-.distance} m ') //} if (step-.mode == 'TRANSIT' && step-.lines [0]) {let line = Line [0] if (line.vehicle == 'BUS') line.title = 'BUS' -${line.title} 'if (line.vehicle == 'RAIL') line.title = 'RAIL' Result.desc.push (' ${line.title}: ${line.geton.title} - > ${line.getoff. Title}, via ${line.station_count}. ')}}) result.polyline = [] result.points = [] result.points = [] i < route.steps.length; i++) { let step = route.steps[i] let polyline = this.getStepPolyline(step) if (polyline) { result.points = Result. The points. The concat (polylines. Points) result. Polylines. Push (polylines)}} / / tag line as a whole according to coordinate this. GetStepPolyline. ColorIndex =  0 let midPointIndex = Math.floor(result.points.length / 2) result.latitude = result.points[midPointIndex].latitude Result.points [0] let startPoint = result.points[0] let endPoint = result.points[0 result.points[result.points.length - 1] result.markers = [ { iconPath: this.startIcon, id: 0, latitude: Startpoint.latitude, longitude: startPoint.longitude, width: 28, height: 28, zIndex: -1, Anchor: {x: 0.5, y: 1} }, { iconPath: this.endIcon, id: 1, latitude: endPoint.latitude, longitude: endPoint.longitude, width: 28, height: 28, zIndex: -1, Anchor: {x: 0.5, y: 1}}] return result},Copy the code

Fourth, the getStepPolyline function gets the polyline for each step of the route

getStepPolyline(step) { let coors = []; // let colorArr = ['#1aad19', '#10aeff', '#d84e43'] let _dottedLine = true if (step.mode == 'WALKING' && step.polyline) { coors.push(step.polyline); _dottedLine = false } else if (step.mode == 'TRANSIT' && step.lines[0].polyline) { coors.push(step.lines[0].polyline); } else {return null} // let kr = 1000000; for (let i = 0 ; i < coors.length; i++){ for (let j = 2; j < coors[i].length; j++) { coors[i][j] = Number(coors[i][j - 2]) + Number(coors[i][j]) / kr; Let coorsArr = []; let coorsArr = []; let _points = []; for (let i = 0 ; i < coors.length; i ++){ coorsArr = coorsArr.concat(coors[i]); } for (let I = 0; i < coorsArr.length; i += 2) { _points.push({ latitude: coorsArr[i], longitude: coorsArr[i + 1] }) } if (! this.getStepPolyline.colorIndex) { this.getStepPolyline.colorIndex = 0 } let colorIndex = Enclosing getStepPolyline. ColorIndex % colorArr. Length enclosing getStepPolyline. ColorIndex++ / / final result polyline let polyline = { width: 7, points: _points, color: colorArr[colorIndex], dottedLine: _dottedLine, arrowLine: BorderColor: '# FFF ', borderWidth: 1} Return polyline}Copy the code

Finally, binding to the map and exporting, we get something like this:

Guangzhou Railway Station -> Guangzhou Tower, 9.88km 30 minutes Metro Line 5 guangzhou Railway Station -> Zhujiang New Town, 7 stops metro Line 3 Zhujiang New Town -> Guangzhou Tower, 1 stopCopy the code

This allows us to do a simple route planning function using the direction interface, and then bind the generated data to the map component. A simple little program, isn’t it? Of course, if you want to do better, call other similar interfaces and refine the details over time.

<map
  id="citymap"
  name="citymap"
  :latitude="currentRoute.latitude"
  :longitude="currentRoute.longitude"
  :polyline="currentRoute.polyline"
  :markers="currentRoute.markers"
  scale="12"
  :subkey="qqMapKey"
  show-location
  show-compass
  enable-rotate
  style="width: 100%; height: 100%;"
></map>
Copy the code

The effect

Author: Prism _JH

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.