SuperMap iClient for Leaflet

Getting Started with Development

  Here we use the World map service published by SuperMap iServer to introduce how to create a simple map application using SuperMap iClient for JavaScript.

Introduce leaflet.js or leaflet.min.js. For Leaflet, please introduce BootCDN host addresss:

<script type="text/javascript" src="https://cdn.bootcss.com/leaflet/1.0.3/leaflet.js"></script>

Introduce iclient9-leaflet.js or iclient9-leaflet.min.js:

<script type="text/javascript" src="https://iclient.supermap.io/dist/iclient9-leaflet.js"></script>

Load services published by iServer to map of Leaflet:

var map = L.map('map');
L.supermap.tiledMapLayer("http://localhost:8090/iserver/services/map/rest/maps/China").addTo(map);view source code »

Run Effects

npm

Install

                            npm install @supermap/iclient-leaflet
                        

ES6 development Example

  Example 1 (import partial modules)

                            import L from 'leaflet';
import {tiledMapLayer} from '@supermap/iclient-leaflet';

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = L.map('map', {
    crs: L.CRS.EPSG4326,
    center: [0, 0],
    maxZoom: 18,
    zoom: 1
});
tiledMapLayer(url).addTo(map);
                        

  Example 2 (import all modules)

                            import L from 'leaflet';
import '@supermap/iclient-leaflet';

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = L.map('map', {
    crs: L.CRS.EPSG4326,
    center: [0, 0],
    maxZoom: 18,
    zoom: 1
});
L.supermap.tiledMapLayer(url).addTo(map);
                        

CommonJS development Example

  Example 1 (import partial modules)

                            var L = require('leaflet');
var tiledMapLayer = require('@supermap/iclient-leaflet').tiledMapLayer;

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = L.map('map', {
    crs: L.CRS.EPSG4326,
    center: [0, 0],
    maxZoom: 18,
    zoom: 1
});
tiledMapLayer(url).addTo(map);
                        

  Example 2 (import all modules)

                            var L = require('leaflet');
require('@supermap/iclient-leaflet');

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = L.map('map', {
    crs: L.CRS.EPSG4326,
    center: [0, 0],
    maxZoom: 18,
    zoom: 1
});
L.supermap.tiledMapLayer(url).addTo(map);
                        

About pacing

  Because iClient uses ES6, in order to be compatible with browsers that do not support ES6, some configuration needs to be performed during the packaging process, including loading images and CSS files and processing the syntax conversion.

  If you use webpack, you need to add the following configuration items in the webpack.config.js.

                            module: {
        rules: [{
            // Load image files, encoding images Which are less than 80k with base64.
            test: /\.(png|jpg|jpeg|gif|woff|woff2|svg|eot|ttf)$/,
            use: [{
                loader: 'url-loader',
                options: {
                    limit: 80000
                }
            }]
        }, {
            // Load CSS files
            test: /\.css$/,
            use: ['css-loader']
        }, {
            // Use the babel-loader to convert ES6 syntax to ES5.
            test: /\.js$/,
            include: [
                path.resolve(__dirname, "node_modules/@supermap/iclient-common"),
                path.resolve(__dirname, "node_modules/@supermap/iclient-leaflet"),
                path.resolve(__dirname, "node_modules/elasticsearch"),
            ],
            loader: 'babel-loader',
            options: {
                presets: ['es2015']
            }
        }]
    }
                        

Projection

You can customize projections via L.Proj.CRS of SuperMap iClient for Leaflet. Bounds, origion, scale array, resolution array can be specified, as shown below:

                                    
var crs = L.Proj.CRS("EPSG:4326", {
    origin: [114.59, 42.31],
    scaleDenominators: [100000, 50000, 25000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 1]
});
map = L.map('map', {
    crs: crs,
    center: [39.79, 116.85],
});
L.supermap.tiledMapLayer(url).addTo(map);
                                        view source code »
                                    
                                

For projections that are not supported or user-defined, you need to define key-value pairs through the Proj4js.defs[] static constant. Proj4js is a projection-related JavaScript script library. Please refer to the following website for details: https://trac.osgeo.org/proj4js/

Currently, Proj4js supports following projections: WGS84, EPSG:4326, EPSG:4269, EPSG:3875, EPSG:3785, EPSG4139,EPSG:4181, EPSG:4272, EPSG:4302, EPSG:21781, EPSG:102113,EPSG:26591,EPSG:26912, EPSG:27200, EPSG:27563, EPSG:41001, EPSG:42304,EPSG:102067, EPSG:102757, EPSG:102758, EPSG:900913, GOOGLE


Proj4js.defs("EPSG:21418","+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=18500000 +y_0=0 +ellps=krass +units=m +no_defs ");
                    

For parameter definition of projections, please refer to https://spatialreference.org; If defined, you can search and view the parameters. For example, for EPSG:21418, the parameters are https://spatialreference.org/ref/epsg/21418/proj4/

For a user-defined projection, you can create the projection by defining EPSGCODE and defs, where defs contains the reference projection parameters including name, projection, conversion to the WGS84 coordinate system (three parameters), major semiaxis, flatterning rate, original latitude, central meridian, standard parallels, east offset, north offset, Unit, etc.


Proj4js.defs("EPSG:10010","+title=Beijing1954 +proj=lcc +towgs84=0.0000,0.0000,0.0000 +a=6378245.0000 +rf=298.3 +lat_0=0.00000000 +lon_0=104.000000000 +lat_1=24.000000000 +lat_2=40.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs");
                            

Compatible with IE 8

The 1.2.0 version of Leaflet does not support IE8 for the time being, use the 1.0.3 instead.

For better compatible with IE 8, except for leaflet.js, iclient9-leaflet.js, you still need to introduce es5-shim.

You can directly download es5-shim.jses5-sham.js, or refer the online addresss:
https://cdn.bootcss.com/es5-shim/4.5.9/es5-shim.js
https://cdn.bootcss.com/es5-shim/4.5.9/es5-sham.js

Add the following code before the <script> tab in the introduced leaflet.js:


<!--[if lte IE 8]>
<script src="your shim js"></script>
<script src="your sham js"></script>
<![endif]-->
                            

See this example stand-alone

Using Map Services

    REST map service functions provided by SuperMap iClient for Leaflet include:

  • Map layer: Supports dynamic layer locationing, dynamic layer overlay
  • Map control: Map dragging, zooming and panning, feature drawing, cache switching, etc.
  • Thematic maps: Unique values map, ranges map, label map, dot density map, graduated symbol map, graph map.
  • Query: Distance query, geometric object query, SQL query, bounds query, nautical chart query
  • Measure:Distance query and area query

Using REST Map Services

  Dynamic Layer Overlay

    A layer is used to load information on the map for display. For one map, you can add one or multiple layers to realize the effects the client wants. You can use addTo() to add a layer to a map. In this example, we add the map for Beijing and Tianjin area to the World map:

                            //Initialize map information
var map = L.map('map', {
crs: L.CRS.EPSG4326,
    center: [40, 118],
    maxZoom: 18,
    zoom: 6
});
//initialize layer
var layerWorld = L.supermap.tiledMapLayer(DemoURL.world);
var layerJingjin = L.supermap.tiledMapLayer(DemoURL.jingjin_map, {
transparent: true,
    opacity: 0.6
});
//load layer
layerWorld.addTo(map);
layerJingjin.addTo(map);
                        

  Run effects

  Distance Measurement

    Construct Servie Parameter Class

    The measurement service parameter class provides the information required by the service request, which provides the query parameter encapsulation of the measurement. Parameters provided include geometry and unit, which are used to define the geometric objects and units of the measurement, with the code as follows:

                            var measureParam = new SuperMap.MeasureParameters();
//Set the vector object ({line} or {Polygon}) to measure, and geometry can obtain via initialization
measureParam.geometry = geometry;
measureParam.unit = SuperMap.Unit.METER;
                        

  Distance Measurement

    Construct Servie Parameter Class

    The measurement service parameter class provides the information required by the service request, which provides the query parameter encapsulation of the measurement. Parameters provided include geometry and unit, which are used to define the geometric objects and units of the measurement, with the code as follows:

                            var measureParam = new SuperMap.MeasureParameters();
//Set the vector object ({line} or {Polygon}) to measure, and geometry can obtain via initialization
measureParam.geometry = geometry;
measureParam.unit = SuperMap.Unit.METER;
                        

    Construct service class and send request

    The measurement service class is responsible for sending requests to the server and getting the query results returned. The service class needs to specify service parameters such as URL, send request information to the server, and then request the complete event via the listener service. The results can be obtained from the event service data class, and handled according to the requirements. Please refer to the following code:

                            //Initialize the service class and set service request key parameters
var measureService = L.supermap.measureService(URL);
//Submit service request, pass service query parameters, get returned results and handle the results according to requirements
measureService.measureDistance(measureParam, function (serviceResult){
    function doSomething(serviceResult);
});
                        

    3. Handle results

    While handling the service request event, we can obtain the result information and display it, and use the form of the pop up window to show the measurement result:

                            function doSomething(serviceResult) {
    var distance = serviceResult.result.distance,
    unit = serviceResult.result.unit;
    var content = "Distance: " + distance + “ ”+unit;
    //Add pop up window at start point marker
    marker.bindPopup(content).openPopup(marker.getLatLng());
}
                        

  Run effects

Using OGC Map Service

  WMS Service

    The WMS layer allows you to access layer services based on the OGC WMS Standard, including other third-party WMS services other than those from iServer. WMS Service conforms to WMS Implementation Specification provided by OGC (Open Geospatial Consortium, the Open Geographical Information Alliance), currently including WMS 1.1.1 and 1.3.0.

    This section will introduce to you how to add WMS layer to display OGC map service data taking WMS_China published by SuperMap iServer as an example.

                            //Initialize map
var url = "https://iserver.supermap.io/iserver/services/map-china400/wms111/China";
var map = L.map('map', {
center: [0, 0],
    maxZoom: 18,
    zoom: 1
});
//Initialize layer
var layer =L.tileLayer.wms(url, {
layers: 'China',
    format: 'image/png',
    transparent: true,
    noWrap: true,
});
//Load layer
layer.addTo(map);
                        

  Run effects

  WMTS Service

    The WMTS layer allows you to access layer services based on the OGC WMTS 1.0.0 Standard, including other third-party WMS services other than those from iServer. WMTS is first service standard to support rest from OGC. Current version is 1.0.0. Currently, three request modes are supported: HTTP KVP (Key-value Pair) mode, SOAP mode, REST mode. Note: Users need to set various types of parameters for the map request: matrixIds、layer、tilematrixSet、url and so on, where the matrixIds will be different due to the standard of the service and the scale set and needs to be set accordingly.

    This section will introduce to you how to add WMTS layer to display OGC map service data taking WMTS_China published by SuperMap iServer as an example.

                            //Initialize map
//Resolution arrary information of the current layer
var res = [];
for (var i = 0; i < 22; i++) {
res.push(165664.43905455674 / (Math.pow(2, i)));
}
var map = L.map('map', {
    center: [0, 0],
    maxZoom: 18,
    zoom: 0,
    crs: L.Proj.CRS("EPSG:3857", '',
        {
            origin: [-2.0037508342789244E7, 2.0037508342789244E7],
            resolutions: res,
            bounds: L.bounds([-2.0037508342789244E7, -2.0037508342789244E7], [2.0037508342789244E7, 2.0037508342789244E7])
         })
});
//Initialize layer
var url = "https://iserver.supermap.io/iserver/services/map-china400/wmts100";
var layer = L.supermap.wmtsLayer(url,
{
layer: "China",
      style: "default",
      tilematrixSet: "Custom_China",
      format: "image/png"
   });
//Load layer
layer.addTo(map);
                        

  Run effects

Using Data Services

    REST data services supported by SuperMap iClient for Leaflet include:

  • Dataset ID Query
  • Dataset Geometry Query
  • Dataset Buffer Query
  • Dataset SQL Query
  • Dataset Editing

Using REST Data Service

  Dataset ID Query

    Dataset ID query queries geographic features with specified IDs in a dataset and display the results on the client. This example queries geographic features with specified IDs in the World dataset.

                            //Initialize map, and add event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = L.map('map', {
preferCanvas: true,
    crs: L.CRS.EPSG4326,
    center: [20, 80],
    maxZoom: 18,
    zoom: 2
});
L.supermap.tiledMapLayer(baseUrl).addTo(map).on("load", function () {
query();
});
//Handle dataset ID query
function query() {
//Dataset ID query service parameters
    var idsParam = new SuperMap.GetFeaturesByIDsParameters({
        IDs: [246, 247],
        datasetNames: ["World:Countries"]
    });
    //Send the request to the server and handle the results returned from the server
var url = "https://iserver.supermap.io/iserver/services/data-world/rest/data";
    L.supermap.featureService(url).getFeaturesByIDs(idsParam, function (serviceResult) {
        L.geoJSON(serviceResult.result.features, {
            onEachFeature: function (feature, layer) {
                //Add pop up event for the results
                layer.bindPopup("ID: " + feature.properties.SMID +
"<br>" + "Country: " + feature.properties.COUNTRY);
             }}).addTo(map);
    });
}
                            
                        

  Run effects

  Dataset SQL Query

    Dataset SQL query queries geographic vector features satisfying a specified SQL condition in a dataset and display the results on the client. This example queries geographic features with specified SMID in the World dataset.

                            //Initialize map, and add event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World",
var map = L.map('map', {
preferCanvas: true,
    crs: L.CRS.EPSG4326,
    center: [0, 0],
    maxZoom: 18,
    zoom: 1
});
L.supermap.tiledMapLayer(baseUrl).addTo(map).on("load", function () {
query();
});
//Handle dataset SQL query
function query() {
//Dataset SQL query service parameters
    var sqlParam = new SuperMap.GetFeaturesBySQLParameters({
        queryParameter: {
                name: "Countries@World",
                attributeFilter: "SMID = 247"
        },
        datasetNames: ["World:Countries"]
    });
    //Send the request to the server and handle the results returned from the server
var url = "https://iserver.supermap.io/iserver/services/data-world/rest/data";
    L.supermap.featureService(url).getFeaturesBySQL(sqlParam, function (serviceResult) {
        //Display results on the map and add pop up window for the results
        L.geoJSON(serviceResult.result.features).addTo(map).bindPopup('SMID = 247');
    });
}

                            
                        

  Run effects

Using Spatial Analyst Services

    Spatial analysis functions supported by SuperMap iClient for Leaflet include:

  • Buffer Analysis
  • Overlay Analysis
  • Surface Analysis
  • Dynamic Segmentation
  • Route Calculate Measure Services
  • Route Locator Point Services
  • Route Locator Line Services

  Sample: Buffer Analysis

    Buffer analysis is an analytical method that automatically establishes a range of regions of a certain width based on the specified distance around the point, line, and polygon features. For example, in environmental governance, a certain width is often drawn around polluted rivers to indicate contaminated areas. At airports, a range of areas are often zoned around a non residential area due to health needs.

    Here we create a round buffer with the buffer radius of 10 meters around a road for Changchun data.

    Set parameters for buffer analysis

                            //Buffer analysis parameters
dsBufferAnalystParams = new SuperMap.DatasetBufferAnalystParameters({
//The dataset name in the datasource used for buffer analysis
   dataset: "RoadLine2@Changchun",
//Set the filter condition for feature set in the dataset
   filterQueryParameter: new SuperMap.FilterParameter({
//Attribute filter condition
       attributeFilter: "NAME='Tuanjie Road'"
   }),
//Set buffer analysis common parameters
   bufferSetting: new SuperMap.BufferSetting({
//Set end type, including FLAT and RROUND
       endType: SuperMap.BufferEndType.ROUND,
//Left radius
       leftDistance: {value: 10},
//Right radius
       rightDistance: {value: 10},
//Set the number of line segments for round buffer
       semicircleLineSegment: 10
   })
});
                            
                        

    Set the buffer analysis service object, which is used to pass parameters specified at the cient side to the server side and receive the data from returned from the server. When a request has been sent to the server and the server has returned the result successfully, the user can handle the results of buffer analysis from the server.

                            //Initialize map, and add event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
crs: L.CRS.NonEarthCRS({
        bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
        origin: L.point(48.4, -55.58)
    }),
    center: [-3375, 5105],
    maxZoom: 18,
    zoom: 6
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
    bufferAnalystProcess();
});
//Define buffer analysis service
function bufferAnalystProcess(){
var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-changchun/restjsr/spatialanalyst"
var bufferServiceByDatasets = L.supermap.spatialAnalystService(serviceUrl);
//Send the request to the server and display the results returned from the server on the map
bufferServiceByDatasets.bufferAnalysis(dsBufferAnalystParams,function(serviceResult)
{
        var result = serviceResult.result;
        resultLayer = L.geoJSON(result.recordset.features, {color: "red"})
resultLayer.addTo(map);
});
}
                            
                        

  Run effects

  Sample: Overlay Analysis

    Overlay analysis is a very important spatial analysis function in GIS. It refers to the process of generating new datasets through a series of set operations on two data sets under the unified spatial Reference system, which aims to extract the new spatial geometry information needed by the user via processing or analyzing spatial data. At the same time, the various attribute information of the data will be processed by the overlay analysis.

    At present, overlay analysis is widely used in resource management, urban construction assessment, land management, agriculture, forestry, animal husbandry, statistics and other fields. The role of overlay analysis in various fields:

  • Resource management is mainly used in the fields of agriculture and forestry to solve the problems of distribution, change and statistics of various resources.
  • Urban construction assessment should be used to analyze the development and change of urban population, economy and construction, and the trend and law of the change.
  • Land and cadastre management involves the change of land use nature, the change of plot boundary and the change of cadastral ownership, which can be accomplished efficiently with high quality under the help of GIS overlay analysis.
  • Ecological and environmental management evaluation is used for regional ecological planning evaluation, environmental status assessment, environmental impact assessment, pollutant reduction and allocation of decision-making support, etc.
  • Geoscience research and application is used for topographic analysis, watershed analysis, land use research, economic geography research, spatial statistical analysis, cartography, etc.

    Here we overlay the administrative boundary of Beijing and Tianjin area and that of neighboring areas.

    Set overlay analysis parameters

                            //Set overlay analysis parameters
var dsOverlayAnalyParams = new SuperMap.DatasetOverlayAnalystParameters({
      sourceDataset: "BaseMap_R@Jingjin",  //The name of the source dataset of overlay analysis
      operateDataset: "Neighbor_R@Jingjin",  //The name of the operate dataset of overlay analysis
      tolerance: 0,  //Tolerance
      operation: SuperMap.OverlayOperationType.UNION  //The type of overlay analysis
});
                            
                        

    Set the overlay analysis service object, which is used to pass parameters specified at the cient side to the server side and receive the data from returned from the server. When a request has been sent to the server and the server has returned the result successfully, the user can handle the results of overlay analysis from the server.

                            //Initialize map, and set event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-jingjin/rest/maps/JingjinPopulationDistribution_ThematicMap",
var map = L.map('map', {
        crs: L.CRS.EPSG4326,
        center: [40.05, 116.85],
        maxZoom: 18,
        zoom: 6
});
L.supermap.tiledMapLayer(baseUrl, { transparent: true, cacheEnabled: false, noWrap: true}).addTo(map) .on("load", function () {
        overlayAnalystProcess();
});
//Define overlay analysis service
function overlayAnalystProcess() {
var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst";
var overlayAnalystService = L.supermap.spatialAnalystService(serviceUrl);
//Send the request to the server and display the results returned from the server on the map
overlayAnalystService.overlayAnalysis(dsOverlayAnalyParams, function(serviceResult) {
    var result = serviceResult.result;
    var resultLayer = L.geoJSON(result.recordset.features)
resultLayer.addTo(map);
);
}
                            
                        

  Run effects

  Sample: Surface Analysis

    Surface analysis refers to mining the hidden information contained in the original data by analyzing datasets or geometric objects. Surface analysis includes extracting isolines and extracting isoregions. Isolines are lines connected with adjacent points with same values, commonly used for contour lines for height, depth, temperature, precipitation, etc. The distribution of isolines reflects the change of the value on the grid surface, and the denser the contour lines are, the more drastic the change of the grid surface values. At places where the contour distribution is sparse, the change of grid surface values is smaller. By extracting isolines, we can find places where the elevation, temperature or precipitation is the same. Meanwhile, the distribution of isolines can also reflect where the value change is steep or gentle. The isoregions is composed by closing adjacent contour lines. The change of the isoregions can intuitively indicate the change between adjacent isolines, such as elevation, precipitation, temperature or atmospheric pressure. Places where the elevation, precipitation or temperature is equivalent can be obtained by extracting the isoregions.

    This section will introduce how to extract contour lines based on temperature resample points of China.

    Set surface analysis parameters

                            //Set clip area
var region = L.polygon([[4010338,0],[4010338,1063524],[3150322,1063524],[3150322,0]]);
//Set surface analysis parameters
var extractParams = new SuperMap.SurfaceAnalystParametersSetting({
datumValue: 0, //The datum value in surface analysis
    interval: 2, //The interval value
    resampleTolerance: 0, //The resample tolerance
    smoothMethod: SuperMap.SmoothMethod.BSPLINE, //The method used for smoothing
    smoothness: 3, //The smoothness of contour lines
    clipRegion: region //The clip object
});
//The surface analysis parameters
var surfaceAnalystParams = new SuperMap.DatasetSurfaceAnalystParameters({
extractParameter: extractParams, //The surface analysis parameters
    dataset: "SamplesP@Interpolation", //The name of the source dataset in overlay analysis
    resolution: 3000, //The resoluton of intermediate results
    zValueFieldName: "AVG_TMP" //The name of the field used for extraction
});
                            
                        

    Set the surface analysis service object, which is used to pass parameters specified at the cient side to the server side and receive the data from returned from the server. When a request has been sent to the server and the server has returned the result successfully, the user can handle the results of surface analysis from the server.

                            //Initialize map, and add event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-temperature/rest/maps/ChinaTemperatureMap";
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([-2640403.63, 1873792.1], [3247669.39, 5921501.4]),
            origin: L.point(-2640403.63, 5921501.4)
        }),
        center: [3580330, 531762],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
        surfaceAnalystProcess();
});
//Process surface analysis service
function surfaceAnalystProcess() {
    //Initialize surface analysis service instance
var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst" ;
var surfaceAnalystService = L.supermap.spatialAnalystService(serviceUrl);
//Send the request to the server and process the resullts
surfaceAnalystService.surfaceAnalysis(surfaceAnalystParams, function (serviceResult) {
L.geoJSON(serviceResult.result.recordset.features, {weight: 3}).addTo(map);
});
}
                            
                        

  Run effects

  Sample: Dynamic Segmentation

    Dynamic segmentation is developed on linear reference. It employs two data structures: route dataset and event table dataset. In real practise, many geographic positions are recorded as the events of features along the line. For example, we tell you that an accident happened in 500m west to the No. 32 corner. Sometimes, over-accurate figures are useless for us in our daily life. However, the relative positions points or lines can help us get the information we want at ease. Linear reference can associate each part of the linear feature to different attribute values under the conditions of not splitting the linear feature into sections. The thought of linear reference can be applied in linear data collection like roads, railways, rivers, etc., public transportation system management, road quality management as well as communication and distribution networks (such as power grids, telephone lines, TV cables, water supply and drainage pipes, etc.).

    This section introduces to you how to show the road traffic (blocked/congested/expedite) in real-time on the client side based on dynamic segmentation technology to prompt motorists to avoid entering the congested road and choose the appropriate route using data for Changchun city road map as the sample data.

    Set parameters including DataReturnOption and generateSpatialDataParams for dynamic segmentation on the client side.

                            //Configure dynamic segmentation parameters
var generateSpatialDataParams = new SuperMap.GenerateSpatialDataParameters({
            routeTable: "RouteDT_road@Changchun",//Route dataset
            routeIDField: "RouteID",//The route ID
            eventTable: "LinearEventTabDT@Changchun",//The event table used to generate spatial data
            eventRouteIDField: "RouteID",//The route ID of the event table used to generate spatial data
            measureField: "",//The measure field of the event table used to generate spatial data
            measureStartField: "LineMeasureFrom",//The from field of the event table
            measureEndField: "LineMeasureTo",//The to field of the event table
            measureOffsetField: "",//The offset field for measure values
            errorInfoField: "",//The error message field
//Set DataReturnOption
            dataReturnOption: new SuperMap.DataReturnOption({
//Set the maximum number of records allowed to be returned
                  expectCount: 1000,
//Set result dataset identification. Because dataReturnMode is set to SuperMap.REST.DataReturnMode.DATASET_ONLY, only the name of the dataset will be returned
                  dataset: "generateSpatialData@Changchun",
//If the user-named result dataset name is the same as the existing dataset, delete the existing data set
                  deleteExistResultDataset: true,
//Set the data return mode to DATASET_ONLY
                  dataReturnMode: SuperMap.DataReturnMode.DATASET_ONLY
            })
});
                            
                        

    Set the dynamic segmentation service object, which is used to pass parameters specified at the cient side to the server side and receive the data from returned from the server. When a request has been sent to the server and the server has returned the result successfully, the user can handle the results of dynamic segmentation from the server.

                            //Initialize map, and set event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangechunCityMap",
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3861.911472192499, 4700],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
        generateSpatialDataAnalystProcess();
});
//Configure dynamic segmentation service
function generateSpatialDataAnalystProcess(){
    var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-changchun/restjsr/spatialanalyst"
var generateSpatialDataService = L.supermap.spatialAnalystService(serviceUrl);
//Send the request to the server and display the results on the client side as thematic map
generateSpatialDataService.generateSpatialData(generateSpatialDataParams, function () {
        //Display the results on the client side as thematic map
        showAnalysisResult_ThemeGridUnique();
});
//When the data is returned, it will be displayed on the client side as thematic map
function showAnalysisResult_ThemeGridUnique() {
        //Create a thematic map instance
        themeService = L.supermap.themeService(baseUrl);
        //Configure thematic map styles
        var style1, style2, style3;
        style1 = new SuperMap.ServerStyle({
            fillForeColor: new SuperMap.ServerColor(242, 48, 48),
            lineColor: new SuperMap.ServerColor(242, 48, 48),
            lineWidth: 1
        });
        style2 = new SuperMap.ServerStyle({
            fillForeColor: new SuperMap.ServerColor(255, 159, 25),
            lineColor: new SuperMap.ServerColor(255, 159, 25),
            lineWidth: 1
        });
        style3 = new SuperMap.ServerStyle({
            fillForeColor: new SuperMap.ServerColor(91, 195, 69),
            lineColor: new SuperMap.ServerColor(91, 195, 69),
            lineWidth: 1
        });
        //Configure thematic map items
        var themeUniqueIteme1, themeUniqueIteme2, themeUniqueIteme3;
        themeUniqueIteme1 = new SuperMap.ThemeUniqueItem({
            unique: "Blocked",
            style: style1
        });
        themeUniqueIteme2 = new SuperMap.ThemeUniqueItem({
            unique: "Congested",
            style: style2
        });
        themeUniqueIteme3 = new SuperMap.ThemeUniqueItem({
            unique: "Expedite",
            style: style3
        });
        var themeUnique = new SuperMap.ThemeUnique({
            uniqueExpression: "TrafficStatus",
            defaultStyle: new SuperMap.ServerStyle({
                fillForeColor: new SuperMap.ServerColor(48, 89, 14),
                lineColor: new SuperMap.ServerColor(48, 89, 14)
            }),
            items: [themeUniqueIteme1, themeUniqueIteme2, themeUniqueIteme3]
        });
        themeParameters = new SuperMap.ThemeParameters({
            themes: [themeUnique],
            datasetNames: ["generateSpatialData"],
            dataSourceNames: ["Changchun"]
        });
        themeService.getThemeInfo(themeParameters, function (serviceResult1) {
            var result = serviceResult1.result;
            if (result && result.newResourceID) {
                themeLayer = L.supermap.tiledMapLayer(baseUrl, {
                    noWrap: true,
                    cacheEnabled: false,
                    transparent: true,
                    layersID: result.newResourceID
                    //opacity: 0.8
                }).addTo(map);
            }
        });
}
                            
                        

  Run effects

  Sample: Route Calculate Measure Services

    Route Calculate Measure calculates the M-value of a point to the starting point of the route. For example, a user may want to know where an accident occurred to determine the distance of the point from a certain intersection.

    Here we calculate the distance from an accident point to the road intersection (route ID 1690). The sample data used is Changchun data.

Interface usage for Route Calculate Measure Service is as follows:

    You need to first initialize the map before the Route Calculate Measure operation.

                            //Initialize map, and set event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
crs: L.CRS.NonEarthCRS({
        bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
        origin: L.point(48.4, -55.58)
    }),
    center: [-3861.91, 4503.62],
    maxZoom: 18,
    zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map) .on("load", function () {
    routeCalculateMeasureProcess();
});
                            
                        

    After the map loading is completed, we will perform the Route Calculate Measure operation. First, we need to get the route object according to the RouteID, and then proceed to subsequent operation.

                            function routeCalculateMeasureProcess() {
    //Set SQL query parameters
    var queryBySQLParams = new SuperMap.QueryBySQLParameters({
queryParams: [
            new SuperMap.FilterParameter({
                name: "RouteDT_road@Changchun",
                attributeFilter: "RouteID=1690"
            })
         ]
    });
//Create SQL service
    var queryBySQLService = L.supermap.queryService(baseUrl);
    //Send the request to the server and handle the results returned from the server
    queryBySQLService.queryBySQL(queryBySQLParams, function (serviceResult) {
        var resultLayer = L.geoJSON(serviceResult.result.recordsets[0].features,
{color: "red"}).addTo(map);
        //Extract the points that form the route to construct the parameter sourceRoute
        var pointsList = [];
        var routeObj = serviceResult.result.recordsets[0].features.features[0].geometry.coordinates[0];
        for (var i = 0; i < routeObj.length; i++) {
            pointsList.push([routeObj[i][1], routeObj[i][0],routeObj[i][2]])
        }
        routeLine = L.polyline(pointsList);
        //Select one query point (the 8th point in the array) from the points that compose the route and add it to the map
        var marker= L.circleMarker([routeObj[7][1], routeObj[7][0]],
{radius: 3, color: 'black'}).addTo(map);
        //Create routeCalculateMeasureService
        var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-changchun/restjsr/spatialanalyst";
        var routeCalculateMeasureService = L.supermap.spatialAnalystService(serviceUrl);
        //Set parameters
var routeCalculateMeasureParameters = new SuperMap.RouteCalculateMeasureParameters({
            "sourceRoute": routeLine,Route Type
            "point": L.point(routeObj[7][0], routeObj[7][1]),//Query point
            "tolerance": 10,
            "isIgnoreGap": false
        });
        //Send the request to the server and handle the results returned from the server routeCalculateMeasureService.routeCalculateMeasure ( routeCalculateMeasureParameters, function (serviceResult) {
           //Add pop up window for the query results and display the obtained M value
           marker.bindTooltip("The M value obtained is: " + serviceResult.result.measure + "", {direction:"top",offset:L.point(0,-5)}).openTooltip();
           });
        });
}
                            
                        

  Run effects

  Sample: Route Locator Point Services

    Route Locator Point determines the point according to the M value. The application scenario is opposite to Route Calculate Measure. It will be used to determine the precise coordinates of an accidient position when we already know the M value from the point to the raod intersection.

    Here we will determine the precise coordinates of an accidient position when we already know the M value from the point to the raod intersection is 10 KM on the route with the ID of 1690. The sample data used here is Changchun data.

    You need to first initialize the map before the Route Locator Point operation.

                            //Initialize map, and add event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
    crs: L.CRS.NonEarthCRS({
        bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
        origin: L.point(48.4, -55.58)
    }),
    center: [-3861.91, 4503.62],
    maxZoom: 18,
    zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map) .on("load", function () {
    routeLocatorProcess();
});
                            
                        

    After the map loading is completed, we will perform the Route Locator Point operation. First, we need to get the route object according to the RouteID, and then proceed to subsequent operation.

                            function routeLocatorProcess() {
    //Set SQL query service parameters
    queryBySQLParams = new SuperMap.QueryBySQLParameters({
        queryParams: [
            new SuperMap.FilterParameter({
                name: "RouteDT_road@Changchun",
                attributeFilter: "RouteID=1690"
            })
         ]
     });
    //Create query service
    var queryBySQLService = L.supermap.queryService(baseUrl);
    //Send the request to the server, handle the results returned from the server, and display the handled results on the map
    queryBySQLService.queryBySQL(queryBySQLParams, function (serviceResult) {
        var resultLayer = L.geoJSON(serviceResult.result.recordsets[0].features,
{color: "red"}).addTo(map);
        //Extract the points that form the route to construct polyline of sourceRoute
        var pointsList = [];
        var routeObj = serviceResult.result.recordsets[0].features.features[0].geometry.coordinates[0];
        for (var i = 0; i < routeObj.length; i++) {
            pointsList.push([routeObj[i][1], routeObj[i][0], routeObj[i][2]])
        }
        var routeLine = L.polyline(pointsList);
//Handle Route Locator Point service
//Set Route Locator Point parameters
    var routeLocatorParams_point = new SuperMap.RouteLocatorParameters({
        "sourceRoute": routeLine, //The route object
        "type": "POINT", //Type, point or line
        "measure": 200, //M value
        "offset": 0, //Offset
        "isIgnoreGap": true //Whether to ignore distance between child objects
    });
//Create spatial analysis service
var serviceUrl =
"https://iserver.supermap.io/iserver/services/spatialanalyst-changchun/restjsr/spatialanalyst";
var routeLocatorService = L.supermap.spatialAnalystService(serviceUrl);
    //Send the request to the server and display the results on the client side after handling
    routeLocatorService.routeLocate(routeLocatorParams_point, function (serviceResult) {
        var layer=L.geoJSON(serviceResult.result.resultGeometry).addTo(map);
        //Add pop up window
        layer.bindTooltip("Point with M value " + routeLocatorParams_point.measure + " found" , {direction:"top", offset:L.point(0,-5)}).openTooltip();
        });
    });
}
                            
                        

  Run effects

  Sample: Route Locator Line Services

    Route Locator Line determines the line object on the route according to the specified range. For example, you need to know the precise position of a line segment when we know there is a line segment blocked.

    Here we introduce how to determine precise position of a line segment if we already know the measure values of the line segment to the road intersection are 10km to 800km.

    You need to first initialize the map before the Route Locator Line operation.

                            //Initialize map, and add event for the map
var baseUrl =
"https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap",
var map = L.map('map', {
crs: L.CRS.NonEarthCRS({
        bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
        origin: L.point(48.4, -55.58)
    }),
    center: [-3861.91, 4503.62],
    maxZoom: 18,
    zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map) .on("load", function () {
    routeLocatorProcess();
});
                            
                        

    After the map loading is completed, we will perform the Route Locator Line operation. First, we need to get the route object according to the RouteID, and then proceed to subsequent operation.

                            function routeLocatorProcess () {
    //Set SQL query service parameters
    queryBySQLParams = new SuperMap.QueryBySQLParameters({
        queryParams: [
            new SuperMap.FilterParameter({
                name: "RouteDT_road@Changchun",
                attributeFilter: "RouteID=1690"
            })
         ]
     });
    //Create query service
    var queryBySQLService = L.supermap.queryService(baseUrl);
    //Send the request to the server, handle the results returned from the server, and display the handled results on the map
    queryBySQLService.queryBySQL(queryBySQLParams, function (serviceResult) {
        var resultLayer = L.geoJSON(serviceResult.result.recordsets[0].features,
{color: "red"}).addTo(map);
        //Extract the points that form the route to construct polyline of sourceRoute
        var pointsList = [];
        var routeObj = serviceResult.result.recordsets[0].features.features[0].geometry.coordinates[0];
        for (var i = 0; i < routeObj.length; i++) {
            pointsList.push([routeObj[i][1], routeObj[i][0], routeObj[i][2]])
        }
        var routeLine = L.polyline(pointsList);
//Handle Route Locator Line
//Set Route Locator Line parameters
    var routeLocatorParams_line = new SuperMap.RouteLocatorParameters({
        "sourceRoute": routeLine, //The route object
        "type": "LINE", //Type, point or line
        "startMeasure": 10, //The from value of the line
        "endMeasure": 800, //The to value of the line
        "isIgnoreGap": true //Whether to ignore distance between child objects
    });
//Create spatial analysis service
var serviceUrl =
"https://iserver.supermap.io/iserver/services/spatialanalyst-changchun/restjsr/spatialanalyst";
var routeLocatorService = L.supermap.spatialAnalystService(serviceUrl);
    //Send the request to the server and display the results on the client side after handling
    routeLocatorService.routeLocate(routeLocatorParams_line, function (serviceResult) {
        var resultLayer1 = L.geoJSON(serviceResult.result.resultGeometry).addTo(map);
    })
}
                            
                        

  Run effects

Using Traffic Network Analysis Service

    Traffic network analysis functions supported by SuperMap iClient for Leaflet include:

  • Optimal Path Analysis
  • Service Area Analysis
  • Travelling Salesman Analysis
  • Closest Facility Analysis
  • Location Allocation Analysis
  • Multiple Travelling Salesmen Analysis

  Sample: Optimal Path Analysis

    The optimal path analysis is to find the route with the minimum impedance between two points in the network. It is necessary to access nodes in the network according to the selection order of nodes. Minimum Impedance can be the shortest time, the lowest cost, the best scenery, the best road conditions, the least bridges, the minimum toll stations, most villages passed and so on.

    Here we introduce how to get the optimal path between two specified points on the map.

    Set findPathParams, including common parameters for traffic network analysis, stops passed, etc.

                            //Traffic network analysis result parameters
var resultSetting = new SuperMap.TransportationAnalystResultSetting({
       returnEdgeFeatures: true, //Whether to include edge collection in the results
       returnEdgeGeometry: true, //Whether to include collection object information in the returned edge feature collection
       returnEdgeIDs: true, //Whether to include ID collection of passed edges in the returned results
       returnNodeFeatures: true, //Whether to include node feature collection in the returned results
       returnNodeGeometry: true, //Whether to include collection object information in the returned node feature collection
       returnNodeIDs: true, //Whether to include ID collection of passed nodes in the returned results
       returnPathGuides: true, //Whether to include path guides collection in the returned results
       returnRoutes: true//Whether to include route object collection in the returned results
});
//Traffic network analysis common parameters
var analystParameter = new SuperMap.TransportationAnalystParameter({
         resultSetting: resultSetting, //The contents of the analysis results
         weightFieldName: "length"//Name of the impedance field
});
//Optimal path analysis parameters
var findPathParams = new SuperMap.FindPathParameters({
         isAnalyzeById: false, //Whether to specify route analysis nodes by node ID
//The array of nodes or facility points passed in optimal path analysis
         nodes: [L.latLng(-3000, 4000), L.latLng(-2500, 5500), L.latLng(-4000, 6900)],
         hasLeastEdgeCount: false, //Whether to perform optimal path analysis according to least edges
         parameter: analystParameter//Traffic network analysis common parameters
});
                            
                        

    Send the request for optimal path analysis to the server and parse the serviceResult returned from the server if the analysis successful. Finally, display the route on the map and provide the path guides.

                            //Initialize map, and add event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3600, 5000],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
        findPathProcess();
});
//Define optimal path analysis service
function findPathProcess(){
    //Add stops
var marker1 = L.marker([-3000, 4000]).addTo(map);
marker1.bindPopup("Stop 1");
var marker2 = L.marker([-2500, 5500]).addTo(map);
marker2.bindPopup("Stop 2");
var marker3 = L.marker([-4000, 6900]).addTo(map);
marker3.bindPopup("Stop 3");
    //Set icon
    var myIcon = L.icon({
            iconUrl: "https://iserver.supermap.io/iserver/iClient/forJavaScript/examples/images/walk.png",
            iconSize: [20, 20]
    });
    var serviceUrl = "https://iserver.supermap.io/iserver/services/transportationanalyst-sample/rest/networkanalyst/RoadNet@Changchun";
    var findPathService = L.supermap.networkAnalystService(serviceUrl);
    //Send the request to the server and display the results on the client side after handling and analysis
    findPathService.findPath(findPathParams, function (serviceResult) {
            var result = serviceResult.result;
            result.pathList.map(function (result) {
                L.polyline(result.route).addTo(map);
                L.geoJSON(result.pathGuideItems, {
                    pointToLayer: function (geoPoints, latlng) {
                        L.marker(latlng, {icon: myIcon}).addTo(map);
                    }
                }).addTo(map);
            })
    });
}
                            
                        

  Run effects

  Sample: Service Area Analysis

    Service area analysis finds the serving area of a supply center in the network. For example, we can calculate the serving area within 30 minutes for a point in the network. Time cost for all points to the specified point within the result area will be less than 30 minutes.

    Here we will do buffer analysis for center points selected. We choose the incrementing value 400, 500, 600... as service radius for the center points according to the selection order.

    The usage of interfaces for service area analysis:

    Set findServiceAreasParams, including traffic network analysis common parameters, passed stops, etc.

                            //Add center points
var marker = L.marker([-3375, 5605]).addTo(map);
//Traffic network analysis result parameters
var resultSetting = new SuperMap.TransportationAnalystResultSetting({
returnEdgeFeatures: true,//Whether to include edge collection in the results
      returnEdgeGeometry: true,//Whether to include collection object information in the returned edge feature collection
      returnEdgeIDs: true,//Whether to include ID collection of passed edges in the returned results
      returnNodeFeatures: true,//Whether to include node feature collection in the returned results
      returnNodeGeometry: true,//Whether to include collection object information in the returned node feature collection
      returnNodeIDs: true,//Whether to include ID collection of passed nodes in the returned results
      returnPathGuides: true,//Whether to include path guides collection in the returned results
      returnRoutes: true//Whether to include route object collection in the returned results
};
//Traffic network analysis common parameters
var analystParameter = new SuperMap.TransportationAnalystParameter({
resultSetting: resultSetting,//The contents of the analysis results
      weightFieldName: "length"//Name of the impedance field
});
var findServiceAreasParams = new SuperMap.FindServiceAreasParameters({
centers: [marker.getLatLng()],//Service stop array
    isAnalyzeById: false,//Whether to specify route analysis nodes by node ID
    parameter: analystParameter,//Traffic network analysis common parameters
    weights: weightsArray//The impedance radius of each stop to provide service
});
                            
                        

    Define the service area analysis service object to pass the parameters specified by the client to the server and receive the result data. If the client has sent the request and the server has returned the results successfully, the user can receive the analysis results and handle the results.

                            //Initialize map, and add event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3500, 5200],
        maxZoom: 18,
        zoom: 3
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
        findServiceAreas();
});
//Define service area analysis service
function findServiceAreas() {
        var serviceUrl = "https://iserver.supermap.io/iserver/services/transportationanalyst-sample/rest/networkanalyst/RoadNet@Changchun";
        var service = L.supermap.networkAnalystService(serviceUrl);
var resultLayer = L.featureGroup().addTo(map);
        parameter.weights = [400 + Math.random() * 100];
        //Send the request to the server and handle the results returned from the server
        service.findServiceAreas(findServiceAreasParams, function (serviceResult) {
              var result = serviceResult.result;
              result.serviceAreaList.map(function (serviceArea) {
                  resultLayer.addLayer(L.geoJSON(serviceArea.serviceRegion));
              });
        });
}
                            
                        

  Run effects

  Sample: Travelling Salesman Analysis

    The travelling salesman analysis is to find the path that passes through a specified set of points. It is unordered path analysis. The traveler can decide the order to pass the nodes to achieve minimum (or closest to minimum) impedance.

    For travelling salesman analysis, if a termination point is specified, the traveler must access termination point last, and the order of other points can be determined by the traveler itself. Here we will introduce how to perform travelling salesman analysis. The sample data used is Changchun data.

    Set findTSPPathsParams, including traffic network analysis common parameters, passed stops, etc.

                            //Traffic network analysis result parameters
var resultSetting = new SuperMap.TransportationAnalystResultSetting({
returnEdgeFeatures: true,//Whether to include edge collection in the results
    returnEdgeGeometry: true,//Whether to include collection object information in the returned edge feature collection
    returnEdgeIDs: true,//Whether to include ID collection of passed edges in the returned results
    returnNodeFeatures: true,//Whether to include node feature collection in the returned results
    returnNodeGeometry: true,//Whether to include collection object information in the returned node feature collection
    returnNodeIDs: true,//Whether to include ID collection of passed nodes in the returned results
    returnPathGuides: true,//Whether to include path guides collection in the returned results
    returnRoutes: true//Whether to include route object collection in the returned results
};
//Traffic network analysis common parameters
var analystParameter = new SuperMap.TransportationAnalystParameter({
resultSetting: resultSetting,//The contents of the analysis results
    weightFieldName: "length"//Name of the impedance field
});
var findTSPPathsParams = new SuperMap.FindTSPPathsParameters ({
isAnalyzeById: false,//Whether to specify passed nodes by Node ID
nodes: nodeArray,//The array of passed nodes for travelling salesman analysis. The array can be array of coordinates or IDs of points
endNodeAssigned: false,//Whether to specify termination point
    parameter: analystParameter//Traffic network analysis common parameters
});
                            
                        

    Define the travelling salesman analysis service object to pass the parameters specified by the client to the server and receive the result data. If the client has sent the request and the server has returned the results successfully, the user can receive the analysis results and handle the results.

                            //Initialize map, and set event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3600, 4700],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
                findTSPPathsProcess();
});
//Multiple travelling salesmen analysis
function findTSPPathsProcess() {
        //Add stops
        var myIcon = L.icon({
            iconUrl: "https://iserver.supermap.io/iserver/iClient/forJavaScript/theme/images/marker.png",
            iconSize: [44, 30]
        });
        var marker4 = L.marker([-1000, 3000], {icon: myIcon}).addTo(map);
        var marker5 = L.marker([-4850, 3760], {icon: myIcon}).addTo(map);
        var marker6 = L.marker([-2700, 8000], {icon: myIcon}).addTo(map);
        //Add pop up windows for supply centers
        marker4.bindPopup("Retail Stop 1");
        marker5.bindPopup("Retail Stop 2");
        marker6.bindPopup("Retail Stop 3");
        //Create multiple travelling salesmen analysis service instance
        var serviceUrl = "https://iserver.supermap.io/iserver/services/transportationanalyst-sample/rest/networkanalyst/RoadNet@Changchun";
        var findTSPPathsService = L.supermap.networkAnalystService(serviceUrl);
//Send the request to the server and handle the results returned
        findTSPPathsService.findTSPPaths(findTSPPathsParams, function (serviceResult) {
            var result = serviceResult.result;
            result.tspPathList.map(function (result) {
                L.geoJSON(result.route).addTo(map);
            });
        });
}
                            
                        

  Run effects

  Sample:Closest Facility Analysis

    Closest facility analysis finds the one or more facility points from the event point with the least cost in the network after giving one event point and a set of facility points. The results contain the optimal path, cost, and direction of travel from the event point to the facility point (or from the facility point to the event point). For example, the incident point is a traffic accident, and facility points are hospitals around. The closest facility analysis is to find the nearest hospitals which can be arrived in 10 minutes. In this case, the position where the accident happens is an event point, and the surrounding hospitals are facility points. Closest facility analysis is actually a path analysis, therefore, you can set barrier edges and nodes in the network to indicates that these edges or nodes can not be crossed.

    Here we will introduce how to find the closest hospital for an accident marked on the map. The sample data used here is Changchun data.

    Set closest facility analysis parameters, including traffic network analysis common parameters, event points, facility points, searching radius, etc.

                            //Traffic network analysis result parameters
var resultSetting = new SuperMap.TransportationAnalystResultSetting({
returnEdgeFeatures: true,//Whether to include edge collection in the results
      returnEdgeGeometry: true,//Whether to include collection object information in the returned edge feature collection
      returnEdgeIDs: true,//Whether to include ID collection of passed edges in the returned results
      returnNodeFeatures: true,//Whether to include node feature collection in the returned results
      returnNodeGeometry: true,//Whether to include collection object information in the returned node feature collection
      returnNodeIDs: true,//Whether to include ID collection of passed nodes in the returned results
      returnPathGuides: true,//Whether to include path guides collection in the returned results
      returnRoutes: true//Whether to include route object collection in the returned results
};
//Traffic network analysis common parameters
var analystParameter = new SuperMap.TransportationAnalystParameter({
      resultSetting: resultSetting,//Contents of the returned results
      turnWeightField: "TurnCost",//Name of the turn weight field
      weightFieldName: "length" //Name of the impedance field
});
//Closest facility analysis parameters
var findClosetFacilitiesParams = new SuperMap.FindClosestFacilitiesParameters({
      //Event point, which is generally the position of the event where facility service is required
      event: L.latLng(-3700, 5000),
      //The number of facility number to be queried
      expectFacilityCount: 1,
      //Facility point collection, which is generally the collection of positions of facilities that offer the service
      facilities: [L.latLng(-3500, 2500), L.latLng(-2500, 5500), L.latLng(-4000, 7000)],
      //Whether the event point and facility points are specified by Node IDs
isAnalyzeById: false,
//Traffic network analysis common parameters
      parameter: analystParameter
});
                            
                        

    Define the closest facility analysis service object to pass the parameters specified by the client to the server and receive the result data. If the client has sent the request and the server has returned the results successfully, the user can receive the analysis results and handle the results.

                            //Initialize map, and set event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3600, 4700],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on('load', function () {
        findClosetFacilitiesProcess();
});
//Set closest facility analysis service
function findClosetFacilitiesProcess(){
        //Add facility points
        var marker1 = L.marker([-3500, 2500]).addTo(map);
        marker1.bindPopup("Facility point 1");
        var marker2 = L.marker([-2500, 5500]).addTo(map);
        marker2.bindPopup("Facility point 2");
        var marker3 = L.marker([-4000, 7000]).addTo(map);
        marker3.bindPopup("Facility point 3");
        //Add event points
        var myIcon = L.icon({
            iconUrl: "https://iserver.supermap.io/iserver/iClient/forJavaScript/theme/images/marker.png",
            iconSize: [44, 30]
        });
        var marker4 = L.marker([-3700, 5000], {icon: myIcon}).addTo(map);
        marker4.bindPopup("Event point");
//Create closest facility analysis service instance
var serviceUrl = "https://iserver.supermap.io/iserver/services/transportationanalyst-sample/rest/networkanalyst/RoadNet@Changchun";
var findClosetFacilitiesService = L.supermap.networkAnalystService(serviceUrl);
//Send request to the server and handle the returned results
findClosetFacilitiesService.findClosestFacilities(findClosetFacilitiesParams, function (serviceResult) {
            var rersult = serviceResult.result;
            rersult.facilityPathList.map(function (result) {
                resultLayer = L.geoJSON(result.route).addTo(map);
            });
        });
}
                            
                        

  Run effects

  Sample: Location Allocation Analysis

    Allocation and Location is to find the optimal location from multiple candidate locations for a facility, by matching the supply and demand based on the objectives and constraints. The Allocation and Location analysis can be applied to the applications such as locating a restaurant, a school, an airport, etc.

    Set location-allocation analysis parameters, including traffic network analysis common parameters, passed stops, etc.

                            //Resource center type, which can be fixed or optional
var supplyCenterType_FIXEDCENTER = SuperMap.SupplyCenterType.FIXEDCENTER,
var supplyCenterType_NULL = SuperMap.SupplyCenterType.NULL,
var supplyCenterType_OPTIONALCENTER = SuperMap.SupplyCenterType.OPTIONALCENTER;
var supplyCenters=[new SuperMap.REST.SupplyCenter({
maxWeight: 500,//The max cost of resource supply center
    nodeID: 139,//The node ID of resource supply center
    resourceValue: 100,//The maximum amount of service or quantity of goods a resource supply center can provide
    type: supplyCenterType_OPTIONALCENTER//Type of resource center
}),
    new SuperMap.SupplyCenter({
        maxWeight: 500,
        nodeID: 1358,
        resourceValue: 100,
        type: supplyCenterType_OPTIONALCENTER

    }),
    new SuperMap.SupplyCenter({
        maxWeight: 500,
        nodeID: 2972,
        resourceValue: 100,
        type: supplyCenterType_OPTIONALCENTER
    }),
    new SuperMap.SupplyCenter({
        maxWeight: 500,
        nodeID: 5523,
        resourceValue: 100,
        type: supplyCenterType_OPTIONALCENTER
   }),
   new SuperMap.SupplyCenter({
        maxWeight: 500,
        nodeID: 1161,
        resourceValue: 100,
        type: supplyCenterType_OPTIONALCENTER
   }),
   new SuperMap.SupplyCenter({
        maxWeight: 500,
        nodeID: 4337,
        resourceValue: 100,
        type: supplyCenterType_OPTIONALCENTER
}),
    new SuperMap.SupplyCenter({
        maxWeight: 500,
        nodeID: 5732,
        resourceValue: 100,
        type: supplyCenterType_NULL
    }),
    new SuperMap.SupplyCenter({
        maxWeight: 500,
        nodeID: 663,
        resourceValue: 100,
        type: supplyCenterType_FIXEDCENTER
    })
];
//Create FindLocationParameters instance
var findLocationParams = new SuperMap.FindLocationParameters({
     expectedSupplyCenterCount: 8, //Number of resource centres expected
     isFromCenter: false, //Whether to start allocating resources from supply center
     nodeDemandField: "Demand", //Node demand field
     turnWeightField: "TurnCost", //Turn weight field
     weightName: "length", //Name of the impedance field
     supplyCenters: supplyCenters //Supply center collection, required
});
                            
                        

    Define the location-allocation analysis service object to pass the parameters specified by the client to the server and receive the result data. If the client has sent the request and the server has returned the results successfully, the user can receive the analysis results and handle the results.

                            //Initialize map, and set event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3600, 4700],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
        findLocationProcess();
});
//Handle location allocation servie results
function findLocationProcess() {
        //Add facility points
        L.marker([-593.56822512495194, 1675.9256791377206]).addTo(map);
        L.marker([-2358.0414663985171, 2820.35101097629]).addTo(map);
        L.marker([-3647.0074300836109, 2909.4396668115278]).addTo(map);
        L.marker([-5616.5950974905827, 1544.5037476378677]).addTo(map);
        L.marker([-2130.4887600981415, 6623.5972101719526]).addTo(map);
        L.marker([-4504.2328567816048, 5482.4979617984973]).addTo(map);
        L.marker([-1627.6012900626256, 6940.6579024271468]).addTo(map);
        L.marker([-5747.5063918659716, 8215.9188781715948]).addTo(map);
//Create location allocation analysis service instance
var serviceUrl = "https://iserver.supermap.io/iserver/services/transportationanalyst-sample/rest/networkanalyst/RoadNet@Changchun";
        var findLocationService = L.supermap.networkAnalystService(serviceUrl);
//Send request to the server and handle the returned results
        findLocationService.findLocation(findLocationParams, function (serviceResult) {
                    L.geoJSON(serviceResult.result.demandResults, {
                        pointToLayer: function (geoJsonPoint, latlng) {
                            return L.circleMarker(latlng, {radius: 1, color: "green"});
                        }
                    }).addTo(map);
                });
}
                            
                        

  Run effects

  Sample: Multiple Travelling Salesmen Analysis

    Multipel travelling salemen analysis is to find the most effective and economic path for the logistics centers to deliver goods to the destinations through a network. Unlike the Path Finding analysis, the Logistics Vehicle Routing Analysis often has more than one start point, that is the logistics centers, and more than one predefined destinations. The purpose of the analysis is to find the paths from the logistics centers to the destinations with the minimum cost in total, or find the path for each logistics center with the minimum cost.

    The results of the multipel travelling salemen analysis will contain the destination responsible by each distribution center, the order of distribution of goods to all destinations, and the corresponding route, which can ensure the minimum cost for each distribution center, or the minimum total cost of all distribution centers.

    Here we analyze the distribution routes of each warehouse distribution center to the user-designated retail stations using the multiple travelling salesmen analysis and travelling salesman analysis. The route with minimum cost for the quality inspector to check the goods regularly at each retail station will be given. The sample data used here is Changchun data.

    Set findMTSPPathsParams, including traffic network analysis common parameters, supply center collection, supply destination collection, distribution mode, etc.

                            //Traffic network analysis result parameters
var resultSetting = new SuperMap.TransportationAnalystResultSetting({
returnEdgeFeatures: true,//Whether to include edge collection in the results
    returnEdgeGeometry: true,//Whether to include collection object information in the returned edge feature collection
    returnEdgeIDs: true,//Whether to include ID collection of passed edges in the returned results
    returnNodeFeatures: true,//Whether to include node feature collection in the returned results
    returnNodeGeometry: true,//Whether to include collection object information in the returned node feature collection
    returnNodeIDs: true,//Whether to include ID collection of passed nodes in the returned results
    returnPathGuides: true,//Whether to include path guides collection in the returned results
    returnRoutes: true//Whether to include route object collection in the returned results
};
//Traffic network analysis common parameters
var analystParameter = new SuperMap.TransportationAnalystParameter({
resultSetting: resultSetting,//The contents of the analysis results
    weightFieldName: "length"//Name of the impedance field
});
//Multiple travelling salesmen analysis parameters
var findMTSPPathsParams = new SuperMap.FindMTSPPathsParameters({
//Supply center collection
centers: [L.latLng(-5500, 6000), L.latLng(-2500, 5500), L.latLng(-3500, 2500)],
//Whether to specify supply centers and destinations via node ID
isAnalyzeById: false,
//Supply destination collection
nodes: [L.latLng(-5000, 5000), L.latLng(-2800, 8000)],
//Whether the distribution mode is Least Total Cost
    hasLeastTotalCost: true,
//Traffic network analysis common parameters
    parameter: analystParameter
});
                            
                        

    Obtain the optimal routes from the distribution centers to distribution destinations by submitting the request parameters of logistic distribution analysis to the server, and parse the returned results from the server.

                            //Initialize map, and set event for the map
var baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap";
var map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3600, 4700],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map).on("load", function () {
        findMTSPPathsProcess();
});
//Handle multipel travelling salemen analysis results
 function findMTSPPathsProcess() {
        //Add distribution centers
        var marker1 = L.marker([-5500, 6000]).addTo(map);
        var marker2 = L.marker([-2500, 5500]).addTo(map);
        var marker3 = L.marker([-3500, 2500]).addTo(map);
        //Add pop up windows for supply centers
        marker1.bindPopup("Distribution center 1");
        marker2.bindPopup("Distribution center 2");
        marker3.bindPopup("Distribution center 3");
        //Add destinations
        var myIcon = L.icon({
            iconUrl: 'https://iserver.supermap.io/iserver/iClient/forJavaScript/theme/images/marker.png',
            iconSize: [44, 30]
        });
        var marker4 = L.marker([-5000, 5000], {icon: myIcon}).addTo(map);
        var marker5 = L.marker([-2800, 8000], {icon: myIcon}).addTo(map);
        //Add pop up windows for supply centers
        marker4.bindPopup("Destination 1");
        marker5.bindPopup("Destination 2");
        //Create multipel travelling salemen analysis service instance
        var serviceUrl = "https://iserver.supermap.io/iserver/services/transportationanalyst-sample/rest/networkanalyst/RoadNet@Changchun";
        var findMTSPPathsService = L.supermap.networkAnalystService(serviceUrl);
        //Send the request to the server and handle the returned results
        findMTSPPathsService.findMTSPPaths(findMTSPPathsParams, function (serviceResult) {
            var result = serviceResult.result;
            result.pathList.map(function (result) {
                L.geoJSON(result.route, {color: "green"}).addTo(map);
            });
        });
}
                            
                        

  Run effects

Using Traffic Transfer Analysis Service

    Traffic Transfer Analysis is introduced below:

  • Define start stop and end stop query function.
  • Perform the traffic transfer query. First of all, we must set the traffic transfer parameters on the client side, define the traffic transfer service, and then send the request to the server. When the results are returned to the cient from the server, the client needs to parse the results and display the results.

    Here we introduce how to perform traffic transfer analysis using the bus line data monitored using the Changchun road data.

    1. Query traffic transfer solutions

    Traffic solution query: This method returns all bus solutions, and the specific route information can be acquired depending on the information presented in the solution. First, you need to set the traffic transfer parameters, including solutionCount, transferTactic, transferPreference, walkingRatio, points, define the traffic transfer service function, Send a request to the server, and parse the traffic transfer result data returned from the server.

                            var map, startMarker, endMarker, tempRedLayer, tempMarker,
   routeFeatureGroup, paths = {transSolutions: null, solutions: null}, info,
   baseUrl = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/ChangchunCityMap",
   serviceUrl = "https://iserver.supermap.io/iserver/services/traffictransferanalyst-sample/restjsr/traffictransferanalyst/Traffic-Changchun";
//Initialize map
map = L.map('map', {
        crs: L.CRS.NonEarthCRS({
            bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
            origin: L.point(48.4, -55.58)
        }),
        center: [-3900, 4700],
        maxZoom: 18,
        zoom: 2
});
L.supermap.tiledMapLayer(baseUrl, {noWrap: true}).addTo(map);
//Set start point
startMarker = L.marker([-5527.73795456, 3111.42533851]).addTo(map)
.bindTooltip("Start point", {
        offset: L.point([0, -10]),
        direction: "top",
        permanent: true
}).openTooltip();
//Set end point
endMarker = L.marker([-4270.0725196, 6055.3431955]).addTo(map)
.bindTooltip("End point", {
         offset: L.point([0, -10]),
         direction: "top",
         permanent: true
}).openTooltip();
routeFeatureGroup = L.featureGroup().addTo(map); //Establish temporary stop layer
tempRedLayer = L.featureGroup().addTo(map); //Establish temporary bus line layer
initResultInfoWin();  //Initialize message box
execTransSolutionsQuery('LESS_TIME'); //Least transfer time query

//Initialize message box
function initResultInfoWin() {
        info = L.control({position: 'topright'});  //Display the message box at the top rigt corner
        info.onAdd = function () {
            this._div = L.DomUtil.create('div', 'panel panel-primary');
            info.update();
            handleMapEvent(this._div, this._map);
            return this._div;
        };
        //Map event
        function handleMapEvent(div, map) {
            if (!div || !map) {
                return;
            }
            div.addEventListener('mouseover', function () {
                map.dragging.disable();
                map.scrollWheelZoom.disable();
                map.doubleClickZoom.disable();
            });
            div.addEventListener('mouseout', function () {
                map.dragging.enable();
                map.scrollWheelZoom.enable();
                map.doubleClickZoom.enable();
            });
        }
        //Message box content update
        info.update = function (transSolutions, transGuide) {
            if (!transSolutions) {
                return;
            }
            var solution, lines, line, dispStatus = "block";
            $("<div class='panel-heading' style='background:steelblue;color: honeydew'>Start point: Auto Repair Shop      End point: Zhongan Mansion<br/>Transfer Solution (Least Time)</div>").appendTo(this._div);
            for (var i = 0, iLen = transSolutions.length; i < iLen; i++) {
                solution = transSolutions[i];
                //Display solution
                var title = "";
                for (var ii = 0, iiLen = solution.linesItems.length; ii < iiLen; ii++) {
                    lines = solution.linesItems[ii];
                    for (var iii = 0, iiiLen = lines.lineItems.length; iii < iiiLen; iii++) {
                        line = lines.lineItems[iii];
                        if (iii !== iiiLen - 1) {
                            title += line.lineName + "/";
                        } else {
                            title += line.lineName;
                        }
                    }
                    if (ii !== iiLen - 1) {
                        title += " → ";
                    }
                }
                $("<div class='transferSolution' id='transferSolution-" + i + "'><span class='transferIndex'>Solution " + (i + 1) + ":</span>" + title + "</div>").appendTo(this._div);
                if (i !== 0) {
                    dispStatus = "none";
                }
                var list = $("<div class='transferInfo' id='transferInfo-" + i + "' style='display:" + dispStatus + "'></div>");
                list.appendTo(this._div);
                //Display table of solution 1 by default
                if (i === 0) {
                    fillTransferInfo(transGuide, transSolutions, 0).appendTo(list);
                    setPopup();
                }
            }
            //Display the corresponding table while clicking a solution
            bindSolutionsClickEvent();
        };
        info.addTo(map);
}
//Display table of solution indexX
function fillTransferInfo(transGuide, transSolutions, indexX) {
        clearLayer();
        if (transGuide && transGuide.items.length) {
            var items = transGuide.items;
            for (var itemIndex = 0, itemLen = items.length; itemIndex < itemLen; itemIndex++) {
                var geometry = items[itemIndex].route;
                routeFeatureGroup.addLayer(L.geoJSON(L.Util.toGeoJSON(geometry)).addTo(map));
            }
        }
        var table = $("<table id='trafficRes' border='1'></table>");
        var startStop = $("<tr></tr>");
        $("<td class='start_transfer' width='10px'></td>").appendTo(startStop);
        $("<td colspan='2'><span class='busLink bgSpan'><span style='display:none'>" + transGuide.items[0].startPosition.x + "," + transGuide.items[0].startPosition.y + "</span>" + transGuide.items[0].startStopName + "</span></td>").appendTo(startStop);
        startStop.appendTo(table);
        var indexY = 0;
        for (var iiii = 0, iiiiLen = transGuide.items.length; iiii < iiiiLen; iiii++) {
            var item = transGuide.items[iiii];
            var tr2 = $("<tr></tr>");
            if (item.isWalking) {
                $("<td class='step_transfer' ></td>").appendTo(tr2);
                $("<td> Walk to: <a class='busLink'><span style='display:none'>" + item.endPosition.x + "," + item.endPosition.y + "</span>" + item.endStopName + "</a></td>").appendTo(tr2);
                $("<td>" + parseInt(item.distance) + " m </td>").appendTo(tr2);
            } else {
                var otherLines = transSolutions[indexX].linesItems[indexY],
                    links = "";
                if (otherLines && otherLines.lineItems.length > 1) {
                    links = "</br> or take: "
                    for (var oti = 0, otLen = otherLines.lineItems.length; oti < otLen; oti++) {
                        var line = otherLines.lineItems[oti];
                        if (item.lineName !== line.lineName) {
                            var other = indexX + "," + indexY + "," + oti + ",0";
                            links += "<a class='busLink'><span style='display:none'>" + other + "</span>" + line.lineName + "</a>";
                        }
                    }
                }
                $("<td class='bus_transfer'></td>").appendTo(tr2);
                var points = item.route.points, pointStr = "";
                for (var i = 0; i < points.length; i++) {
                    pointStr += points[i].x + " " + points[i].y;
                    if (i != points.length - 1) {
                        pointStr += ",";
                    }
                }
                $("<td> Take <a class='busLink'>" + item.lineName + "<span style='display:none'>" + pointStr + "</span></a>, at <a class='busLink'><span style='display:none'>" + item.endPosition.x + "," + item.endPosition.y + "</span>" + item.endStopName + "</a> Get off " + links + "</td>").appendTo(tr2);
                $("<td>" + item.passStopCount + " stop </td>").appendTo(tr2);
                indexY++;
            }
            tr2.appendTo(table);
        }
        var endStop = $("<tr></tr>");
        endStop.appendTo(table);
        $("<td class='end_transfer' width='10px'></td>").appendTo(endStop);
        $("<td colspan='2'><span class='busLink bgSpan'><span style='display:none'>" + transGuide.items[transGuide.items.length - 1].endPosition.x + "," + transGuide.items[transGuide.items.length - 1].endPosition.y + "</span>" + transGuide.items[transGuide.items.length - 1].endStopName + "</span></td>").appendTo(endStop);
        return table;
}

//Define execTransSolutionsQuery
function execTransSolutionsQuery(tactic) {
    //Clear results of the previous solution
    info.remove();
    paths.points = [26, 180];
//Configure TransferSolutionParameters
    var params = new SuperMap.TransferSolutionParameters({
            solutionCount: 6,//The maximum transfer guide count
            transferTactic: tactic,//Type of bus transfer strategy
            walkingRatio: 10,//Weight ratio of walking and bus consumption
            points: paths.points //Starting point coordinates
    });
var serviceUrl = "https://iserver.supermap.io/iserver/services/traffictransferanalyst-sample/restjsr/traffictransferanalyst/Traffic-Changchun";
//Send the request to the server and handle the results returned from the server
    L.supermap.trafficTransferAnalystService(serviceUrl)
            .analysisTransferSolution(params, function (serviceResult) {
                if (serviceResult.error) {
                    alert("Error: " + serviceResult.error.errorMsg);
                }
                transferSolutionsSucceed(serviceResult.result);
     });
}

//The returned results when implemented successfully
function transferSolutionsSucceed(result) {
        clearLayer();
        info.addTo(map);
        //Overlay symbol information on the map
//transGuide:Records the traffic transfer guidance scheme from the starting point to the terminating point
//transGuide is composed of objects of the TransferGuideItem type
//Each TransferGuideItem can be a transfer segment or walking route. The type of object can return the number of items in transGuide
//The total distance and cost can be guided according to TransferGuideItem
//transSolutions: The transfer times are the same in all bus routes within a transfer scheme.
        var transGuide = result.defaultGuide,
            transSolutions = result.solutionItems,
            solutions = [];
        for (var j = 0; j < transSolutions.length; j++) {
            var linesItems = transSolutions[j].linesItems, transSolution = [];
            for (var jj = 0; jj < linesItems.length; jj++) {
                var lineItems = linesItems[jj].lineItems, items = [];
                for (var jjj = 0; jjj < lineItems.length; jjj++) {
                    var lineItem = lineItems[jjj];
                    items.push("{'lineID':" + lineItem.lineID +
                        ",'startStopIndex':" + lineItem.startStopIndex +
                        ",'endStopIndex':" + lineItem.endStopIndex + "}"
                    );
                }
                transSolution.push(items);
            }
            solutions.push(transSolution);
        }
        paths["transSolutions"] = transSolutions;
        paths["solutions"] = solutions;
        if (!transGuide || !transSolutions) return;
        info.update(transSolutions, transGuide);
}

//Clear all result layers
function clearLayer() {
        if (routeFeatureGroup) {
            routeFeatureGroup.clearLayers();
        }
        if (tempRedLayer) {
            tempRedLayer.clearLayers();
        }
        if (tempMarker) {
            tempMarker.remove();
        }
}
                            
                        

    2. Bus route query

    Obtain the detailed information of a bus route according to the travel scheme obtained by transferSolutions.

                            //Click on a solution to get a specific route
function bindSolutionsClickEvent() {
        for (var i = 0; i < 6; i++) {
            $("#transferSolution-" + i).click(toggleGuideItems);
        }
        function toggleGuideItems(e) {
            for (var j = 0; j < 6; j++) {
                $("#transferInfo-" + j).hide(500);
            }
            var id = parseInt(e.currentTarget.id.split("-")[1]);
            $("#transferInfo-" + id).show(500);
            //Construct transferLines passed into iServer
            var transLines = [];
            for (var i = 0; i < paths.solutions[id].length; i++) {
                var trans = paths.solutions[id][i][0];
                transLines.push(trans);
            }
            execTransPathQuery(id, transLines);
        }
}

//Get detailed information about the bus route
function execTransPathQuery(id, transLines) {
//Set bus route parameters
        var params = new SuperMap.TransferPathParameters({
            points: paths["points"], //Starting point coordinates
            transferLines: transLines //Current transfer route, including Route ID, starting and ending points, etc.
        });
        //Send the request to the server and handle the results returned from the server
        L.supermap.trafficTransferAnalystService(serviceUrl)
            .analysisTransferPath(params, function (serviceResult) {
                $("#transferInfo-" + id).empty();
                var transGuide = serviceResult.result;
                transSolutions = paths["transSolutions"];
                map.setView([-3900, 4700], 2);
                fillTransferInfo(transGuide, transSolutions, id)
.appendTo($("#transferInfo-" + id));
                setPopup();
            });
}

//Show the temporary stops and routes queried on the map
function setPopup() {
        $(".busLink").click(function () {
            tempRedLayer.clearLayers(); //Clear the temporary route layer
            if (tempMarker) tempMarker.remove();  //Clear the temporary stop layer
            var points = this.children[0].innerText.split(","), lonLat;
            if (points.length === 2) {
                lonLat = L.latLng(points[1], points[0]);
                tempMarker = L.marker(lonLat).addTo(map);
                map.setView(lonLat);
            } else if (points.length === 4 && points[3] === "0") {
                var linesItems = paths["solutions"][points[0]], lineStr = "[";
                for (var i = 0; i < linesItems.length; i++) {
                    var lineItem = linesItems[i][0], j = parseInt(points[1]);
                    if (i !== j) {
                        lineStr += lineItem;
                    } else if (i === j) {
                        lineItem = linesItems[points[1]][points[2]];
                        lineStr += lineItem;
                    }
                    if (i !== linesItems.length - 1) {
                        lineStr += ",";
                    }
                }
                lineStr += "]";
                $("#transferInfo-" + points[0]).hide(500);
                execTransPathQuery(points[0], lineStr);
                $("#transferInfo-" + points[0]).show(500);
            } else {
                var linePoints = [];
                for (var i = 0; i < points.length; i++) {
                    var arr = points[i].split(" ");
                    var point = [arr[1], arr[0]];
                    linePoints.push(point);
                }
                var lineString = L.polyline(linePoints, {color: "red"}).addTo(map);
                tempRedLayer.addLayer(lineString);
                map.setView(lineString.getBounds().getCenter(), 3);
            }
        });
}
                            
                        

  Run effects

  Here only the route with least time cost will display. The query effect is as shown below:

Using Distributed Analysis Services

    Distributed analysis services supported by SuperMap iClient for Leaflet include:

  • Density Analysis
  • Point Aggregation Analysis
  • Single Object Query Analysis
  • Region Summary Analysis
  • Vector Clip Analysis

  Sample: Density Analysis

    Density analysis in distributed analysis services includes simple point density analysis and kernel density analysis.

  • Simple point density analysis: Calculates the measure value per unit of the specified neighborhood area of a point. The value is calculated by dividing the sum of the measured values by the area of the specified neighborhood, and the density values will be added at the neighborhood superposition of the points. The density value of each output grid cell is the sum of density values of all the adjacent density values superimposed on the grid. The unit of the result grid is the reciprocal of the square of the original dataset unit. For example, if the original dataset unit is meter, then the result grid value unit is per square meter.
  • Kernel density analysis: Calculates the point and line element measurement values within the specified neighborhood range. In a nutshell, it can directly reflect the distribution of discrete measurement values in the continuous region. The result is a smooth surface with small peripheral value and the grid value is the unit density, which is reduced to 0 at the neighborhood boundary. Kernel density analysis can be used to calculate population density, building density, crime report access, tourism area density monitoring, chain store operation analysis and so on.

    Here we perform a simple point density analysis on registered big data, and the grid surface type is quadrilateral grid.

    Set kernelDensityJobParams, including dataset, analysis method, analysis type, grid size, etc.

                            //Density analysis parameters
var kernelDensityJobParams = new SuperMap.KernelDensityJobParameter({
//Name of the registered dataset
datasetName: "newyork_taxi_2013_01_14k_csv_newyork_taxi_2013-01_14k",
//Grid size. For the quadrilateral, it is the grid length. For hexagonal meshes, it is the distance from the hexagonal vertex to the center point
    resolution: 80,
//Analysis method, specify whether the analysis method is simple point density analysis, or kernel density analysis. 0 represents the former, and 1 represents the latter
    method:0,
//Grid surface type, specify whether the grid unit is a quadrilateral grid or a hexagonal grid. 0 represents the former, and 1 represents the latter
    meshType:0,
//Specifies the field index column number collection of the weight value of the points to be analyzed, and the field index starts at 0. The format is as follows: col7, col8
    fields: col7,col8,
    query: Bounds, //Analysis bounds
    radius: 300, //The impact radius of the analysis
    meshSizeUnit: Meter, //Grid size unit
radiusUnit: Meter, //Search radius unit
    areaUnit: SquareMile, //Area unit
});
                            
                        

    Submit the request for kernel analysis to the server, parse the results returned from the server, and display the results on the map.

                            //Initialize map
var map = L.map('map', {
crs: L.CRS.TianDiTu_WGS84,
    center: [40.75, -73.95],
    maxZoom: 18,
    zoom: 12
}),
//Add Tianditu layer on the map
L.supermap.tiandituTileLayer("http://t{s}.tianditu.com/vec_c/wmts", {
    layer: "vec",
    tilematrixSet: "c"
}).addTo(map);

//Create distributed analysis service
var processingUrl ="http://localhost:8090/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new L.supermap.processingService(processingUrl);
//Submit the request for kernel analysis to the server, parse the results returned from the server, and display the results on the map.
processingService.addKernelDensityJob(kernelDensityJobParams, function (serviceResult) {
//Pop a warning box and display error message for parsing failure
if (serviceResult.error) {
        var errorMsg = serviceResult.error.errorMsg || "code: " + serviceResult.error.code;
        showAlert("Create failure! 
" + errorMsg, false); return; } //Process the results and display the results on map if the analysis is successful serviceResult.result.setting.serviceInfo.targetServiceInfos.map(function (info) { if (info.serviceType === 'RESTMAP') { SuperMap.FetchRequest.get(info.serviceAddress + '/maps') .then(function(response) {return response.json();}).then(function (result) { var mapUrl = result[0].path; var layer = L.supermap.imageMapLayer(mapUrl, {noWrap: true, transparent: true}); layer.addTo(map); }); } }); });

  Run effects

  Sample: Point Aggregation Analysis

    Point aggregation analysis refers to a spatial analysis operation for making aggregation maps for point datasets. divide the point elements of a map according to surface or polygons, and then calculate the number of points in each surface object, which will be regarded as the statistic value of the surface object. The weights of the points can also be introduced, and the weighted values of the interior points of the surface objects are considered as the statistic values of the surface objects. Based on the statistical values of the surface objects, the values will be sorted and the surface objects will be filled with color ramp.

    Currently supported point aggregation analysis types include: grid surface aggregation and polygon aggregation, in which grid surface aggregation can be divided into quadrilateral grids and hexagonal grids.

    Here we will implement a point aggregation analysis on the registered big data. The aggregation type is a grid surface aggregation, and the grid surface type is quadrilateral.

    Set summaryMeshJobParam, including dataset, aggregation type, statistical mode, grid size, etc.

                            //Point aggregation analysis parameters
var summaryMeshJobParam = new SuperMap.SummaryMeshJobParameter({
//Name of the registered dataset
datasetName: "newyork_taxi_2013_01_14k_csv_newyork_taxi_2013-01_14k",
//Grid size. For the quadrilateral, it is the grid length. For hexagonal meshes, it is the distance from the hexagonal vertex to the center point
    resolution: 80,
//Grid surface type, specify whether the grid unit is a quadrilateral grid or a hexagonal grid. 0 represents the former, and 1 represents the latter
    meshType:0,
//Specifies the field index column number collection of the weight value of the points to be analyzed, and the field index starts at 0. The format is as follows: col7, col8
    fields: col7,
    query: Bounds, //Analysis bounds
    statisticModes:,//Statistics mode, which needs to be consistent with the number of weight value fields
    type:, SummaryType//Aggregation type, specifies whether the aggregation type is a grid surface aggregation or polygon aggregation.
    //regionDataset: 'regionDataset', Aggregation surface dataset, used during polygon aggregation
});
                            
                        

    Submit the request for point aggregation analysis to the server, parse the results returned from the server, and display the results on the map.

                            //Initialize map
var map = L.map('map', {
crs: L.CRS.TianDiTu_WGS84,
    center: [40.75, -73.95],
    maxZoom: 18,
    zoom: 12
}),
//Add Tianditu layer on the map
L.supermap.tiandituTileLayer("http://t{s}.tianditu.com/vec_c/wmts", {
    layer: "vec",
    tilematrixSet: "c"
}).addTo(map);

//Create distributed analysis service
var processingUrl ="http://localhost:8090/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new L.supermap.processingService(processingUrl);
//Submit the request for point aggregation analysis to the server, parse the results returned from the server, and display the results on the map.
processingService.addSummaryMeshJob(summaryMeshJobParam,function(serviceResult){
//Pop a warning box and display error message for parsing failure
if (serviceResult.error) {
        var errorMsg = serviceResult.error.errorMsg || "code: " + serviceResult.error.code;
        showAlert("Create failure! 
" + errorMsg, false); return; } //Process the results and display the results on map if the analysis is successful serviceResult.result.setting.serviceInfo.targetServiceInfos.map(function (info) { if (info.serviceType === 'RESTMAP') { SuperMap.FetchRequest.get(info.serviceAddress + '/maps') .then(function(response) {return response.json();}).then(function (result) { var mapUrl = result[0].path; var layer = L.supermap.imageMapLayer(mapUrl, {noWrap: true, transparent: true}); layer.addTo(map); }); } }); });

  Run effects

  Sample: Single Object Query Analysis

    Spatial query is a query method that selects map features based on their spatial relationships to other feature. For example, if you want to know the number of five-star hotels within 5 km of Olympic venues in Beijing, you can first make a 5 km buffer of the Olympic venues; search the hotels within these buffers using the Containing query method; then, from the result hotels, find the hotels whose star level is 5 using attribute query and the final result can be obtained.

    The single object spatial query refers to spatial query with only one query object. If there are multiple objects in the query object dataset, the object with the smallest SmID will serve as the query object.

    Here we perform a single object query analysis on the registered big data, where the spatial query mode is intersect.

    Set singleObjectQueryJobsParam, including source dataset, query object dataset, spatial query mode.

                            //Single object query analysis parameters
var singleObjectQueryJobsParam = new SuperMap.SingleObjectQueryJobsParameter({
datasetName: 'ProcessingData_processing_newyorkZone_R', //Name of the registered dataset
datasetQuery: 'ProcessingData_processing_singleRegion_R', //Name of the dataset where the query objects are
mode:SpatialQueryMode //Spatial query mode
});
                            
                        

    Submit the request for single object query analysis to the server, parse the results returned from the server, and display the results on the map.

                            //Initialize map
var map = L.map('map', {
crs: L.CRS.TianDiTu_WGS84,
    center: [40.75, -73.95],
    maxZoom: 18,
    zoom: 12
}),
//Add Tianditu layer on the map
L.supermap.tiandituTileLayer("http://t{s}.tianditu.com/vec_c/wmts", {
    layer: "vec",
    tilematrixSet: "c"
}).addTo(map);

//Create distributed analysis service
var processingUrl ="http://localhost:8090/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new L.supermap.processingService(processingUrl);
//Submit the request for single object query analysis to the server, parse the results returned from the server, and display the results on the map.
processingService.addQueryJob(singleObjectQueryJobsParam,function(serviceResult){
//Pop a warning box and display error message for parsing failure
if (serviceResult.error) {
        var errorMsg = serviceResult.error.errorMsg || "code: " + serviceResult.error.code;
        showAlert("Create failure! 
" + errorMsg, false); return; } //Process the results and display the results on map if the analysis is successful serviceResult.result.setting.serviceInfo.targetServiceInfos.map(function (info) { if (info.serviceType === 'RESTMAP') { SuperMap.FetchRequest.get(info.serviceAddress + '/maps') .then(function(response) {return response.json();}).then(function (result) { var mapUrl = result[0].path; var layer = L.supermap.imageMapLayer(mapUrl, {noWrap: true, transparent: true}); layer.addTo(map); }); } }); });

  Run effects

  Sample: Region Summary Analysis

    Region summary analysis refers to a spatial analysis for making aggregation maps for line and region datasets. The map lines and region features are divided according to grid surface or polygons, and then statistics will be done to the lines or regions in each grid cell according to standard attribute field or weight field. The statistical results will be regarded as the grid cell statistical values. Finally, the statistical values will be sorted and the grid cells will be rendered.

    The concept of regional summary analysis is similar to that of point aggregation analysis. The difference is that point aggregation analysis does statistical calculation on point datasets, while the region summary analysis does statistical calculation for line and region datasets. For regional summary analysis, there are two statistical methods for the statistical values of grid cells: statistics based on standard attribute fields and weighted fields.

    Here we perform a region summary analysis on the registered big data, where the region summary type is grid surface and the grid surface type is quadrilateral.

    Set summaryRegionJobParam, including dataset, summary type, grid region summary type, etc.

                            //Region summary analysis parameters
var summaryRegionJobParam = new SuperMap.SummaryRegionJobParameter({
datasetName: 'ProcessingData_processing_newyorkZone_R', //Name of the registered dataset
    //regionDataset: 'regionDataset', Aggregation region dataset, used during polygon aggregation
    type: SummaryType, //Summary type, which can be grid surface summary and polygon summary
//Grid surface type, specify whether the grid unit is a quadrilateral grid or a hexagonal grid. 0 represents the former, and 1 represents the latter
    meshType:0,
    query: Bounds, //Analysis bounds
    standardSummaryFields: true, //Whether to do statistics based on standard attribute field
    //The statistical mode while doing statistics based on standard attribute field
    standardStatisticModes: StatisticAnalystMode,
    standardFields: "LocationID", //The field name when while doing statistics based on standard attribute field
    weightedFields:false, //Whether to do statistics based on weight field
    weightedStatisticModes: "", //The statistical mode while doing statistics based on weight field
weightedSummaryFields: "",//The field name while doing statistics based on weight field
//Grid size. For the quadrilateral, it is the grid length. For hexagonal meshes, it is the distance from the hexagonal vertex to the center point
    resolution:100,
    meshSizeUnit: Meter, //Grid size unit
    sumShape:true //Whether to do statistics on length or area
});
                            
                        

    2. Submit the request for region summary analysis to the server, parse the results returned from the server, and display the results on the map.

                            //Initialize map
var map = L.map('map', {
crs: L.CRS.TianDiTu_WGS84,
    center: [40.75, -73.95],
    maxZoom: 18,
    zoom: 12
}),
//Add Tianditu layer on the map
L.supermap.tiandituTileLayer("http://t{s}.tianditu.com/vec_c/wmts", {
    layer: "vec",
    tilematrixSet: "c"
}).addTo(map);

//Create distributed analysis service
var processingUrl ="http://localhost:8090/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new L.supermap.processingService(processingUrl);
//Submit the request for region summary analysis to the server, parse the results returned from the server, and display the results on the map.
processingService.addSummaryRegionJob(summaryRegionJobParam,
function(serviceResult){
//Pop a warning box and display error message for parsing failure
if (serviceResult.error) {
        var errorMsg = serviceResult.error.errorMsg || "code: " + serviceResult.error.code;
        showAlert("Create failure! 
" + errorMsg, false); return; } //Process the results and display the results on map if the analysis is successful serviceResult.result.setting.serviceInfo.targetServiceInfos.map(function (info) { if (info.serviceType === 'RESTMAP') { SuperMap.FetchRequest.get(info.serviceAddress + '/maps') .then(function(response) {return response.json();}).then(function (result) { var mapUrl = result[0].path; var layer = L.supermap.imageMapLayer(mapUrl, {noWrap: true, transparent: true}); layer.addTo(map); }); } }); });

  Run effects

  Sample: Vector Clip Analysis

    Vector clip analysis is to clip the vector dataset, including internal clip and external clip. Internal clip maintains the portion within the clip area. External clip preserves the portion of dataset that is not within the clip area.

    The vector clip analysis in distributed analysis service supports only one clip object. If there are multiple objects in the clip object dataset, the object with the smallest SmID will serve as the clip object.

    Here we perform a vector clip analysis on the registered big data, employing the internal clip mode.

    Set vectorClipJobsParam, including source data, clip object, clip object dataset, clip analysis mode.

                            //Vector clip analysis parameters
var vectorClipJobsParam = new SuperMap.VectorClipJobsParameter({
datasetName: 'ProcessingData_newyork_taxi_2013-01_14k', //Name of the registered dataset
    datasetOverlay: 'ProcessingData_processing_singleRegion_R',//Name of the dataset where the clip object is
    mode:ClipAnalystMode //Clip analysis mode
});
                            
                        

    Submit the request for vector clip analysis to the server, parse the results returned from the server, and display the results on the map.

                            //Initialize map
var map = L.map('map', {
crs: L.CRS.TianDiTu_WGS84,
    center: [40.75, -73.95],
    maxZoom: 18,
    zoom: 12
}),
//Add Tianditu layer on the map
L.supermap.tiandituTileLayer("http://t{s}.tianditu.com/vec_c/wmts", {
    layer: "vec",
    tilematrixSet: "c"
}).addTo(map);

//Create distributed analysis service
var processingUrl ="http://localhost:8090/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new L.supermap.processingService(processingUrl);
//Submit the request for vector clip analysis to the server, parse the results returned from the server, and display the results on the map.
processingService.addVectorClipJob(vectorClipJobsParam, function(serviceResult){
//Pop a warning box and display error message for parsing failure
if (serviceResult.error) {
        var errorMsg = serviceResult.error.errorMsg || "code: " + serviceResult.error.code;
        showAlert("Create failure! 
" + errorMsg, false); return; } //Process the results and display the results on map if the analysis is successful serviceResult.result.setting.serviceInfo.targetServiceInfos.map(function (info) { if (info.serviceType === 'RESTMAP') { SuperMap.FetchRequest.get(info.serviceAddress + '/maps') .then(function(response) {return response.json();}).then(function (result) { var mapUrl = result[0].path; var layer = L.supermap.imageMapLayer(mapUrl, {noWrap: true, transparent: true}); layer.addTo(map); }); } }); });

  Run effects

Using Data Stream Services

                            //Create real time data layer
var urlDataFlow = "ws://localhost:8091/iserver/services/dataflow/dataflow";
var dataFlowLayer = L.supermap.dataFlowLayer(urlDataFlow, {
    //Optional, elements within the GeoJSON filter will be returned
geometry:{coordinates:[[[116.38,39.87],[116.41,39.87],[116.41,39.84],[116.38, 39.84],[116.38,39.87]]],type:"Polygon"},
//Optional, return excluded fields
    excludeField:["id"],
//Optional, return feature coordinate system
	 prjCoordSys:4326
 });
 dataFlowLayer.addTo(map);
                            
                        

  The following graph shows the effects of real-time data at different times, and you can see that the data is displayed in different locations.

  Run effects


Using Address Matching Services

    SuperMap iClient for Leaflet supports address matching service, which includes forward address matching and reverse address matching. Users can find the location using address, and they can also get the address of a location on the map.

    Here we introduce how to perform address matching using China_4326.

    Sample: Forward Address Matching

    Forward address matching obtains geographic coordinates and structured and detailed address description based on address description, city bounds.

                            //Initialize map
var baseUrl = 'https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China_4326';
var map = L.map('map', {
crs: L.CRS.EPSG4326,
    center: [39.914714, 116.383572],
    maxZoom: 18,
    zoom: 11
});
L.supermap.tiledMapLayer(baseUrl).addTo(map);
//Forward matching parameters
var geoCodeParam = new SuperMap.GeoCodingParameter({
address: "SuperMap", //Address
    fromIndex:0, //Min index
    toIndex:10, //Max index
    filters: "Company", //Filter condition
    prjCoordSys:{epsgcode26}, //Set coordinates
    maxReturn:3 //Max results
});
//Createm address matching service
var addressUrl = "https://iserver.supermap.io/iserver/services/addressmatch-Address/restjsr/v1/address",
var addressMatchService = L.supermap.addressMatchService(addressUrl);
//Send request to the server to operate forward address matching. The server will return the results and the results will be handled
addressMatchService.code(geoCodeParam, match);
//Handle the results and display the results on the map and add pop up window
function match(obj) {
obj.result.map(function (item) {
        var marker = L.marker([item.location.y, item.location.x]);
        decodeMarkers.push(marker);
        var innerHTML = "";
        innerHTML += "Address:" + item.address + "<br>";
        var x = Number(item.location.x.toString().match(/^\d+(?:\.\d{0,2})?/));
        var y = Number(item.location.y.toString().match(/^\d+(?:\.\d{0,2})?/));
        innerHTML += "Coordinates:[" + x + "," + y + "]<br>";
        if (item.score > 0) {
            innerHTML += "Matching rate:" + item.score + "<br>";
        }
        innerHTML += "Filter field:" + item.filters + "<br>";
            marker.bindPopup(innerHTML);
        });
        for (var i = 0; i < decodeMarkers.length; i++) {
            decodeMarkers[i].addTo(map);
        }
        map.setView(L.latLng(39.914714, 116.383572), 10);//Set map display bounds
}
                            
                        

  Run effects

    Sample: Reverse Address Matching

    Get the corresponding address description according to reverse address matching based on input address coordinates

                            //Initialize map
var baseUrl = 'https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China_4326';
var map = L.map('map', {
crs: L.CRS.EPSG4326,
    center: [39.914714, 116.383572],
    maxZoom: 18,
    zoom: 11
});
L.supermap.tiledMapLayer(baseUrl).addTo(map);
//Reverse matching parameters
var geoDecodeParam = new SuperMap.GeoDecodingParameter({
x:116.3518541194, //X coordinate
y:40.00097839595, //Y coordinate
    fromIndex:0, //Min index
    toIndex:10, //Max index
    filters: "", //Filter field
    prjCoordSys:{epsgcode26}, //Set coordinates
    maxReturn:3, //Max results
geoDecodingRadius:1000 //Search radius
});
//Create address matching service
var addressUrl = "https://iserver.supermap.io/iserver/services/addressmatch-Address/restjsr/v1/address",
var addressMatchService = L.supermap.addressMatchService(addressUrl);
//Send request to the server to operate forward address matching. The server will return the results and the results will be handled
addressMatchService.decode(geoDecodeParam, match);
//Handle the results and display the results on the map and add pop up window
function match(obj) {
obj.result.map(function (item) {
        var marker = L.marker([item.location.y, item.location.x]);
        decodeMarkers.push(marker);
        var innerHTML = "";
        innerHTML += "Addresss:" + item.address + "<br>";
        var x = Number(item.location.x.toString().match(/^\d+(?:\.\d{0,2})?/));
        var y = Number(item.location.y.toString().match(/^\d+(?:\.\d{0,2})?/));
        innerHTML += "Coordinates:[" + x + "," + y + "]<br>";
        if (item.score > 0) {
            innerHTML += "Matching rate:" + item.score + "<br>";
        }
        innerHTML += "Filter field:" + item.filters + "<br>";
            marker.bindPopup(innerHTML);
        });
        for (var i = 0; i < decodeMarkers.length; i++) {
            decodeMarkers[i].addTo(map);
        }
        map.setView(L.latLng(39.914714, 116.383572), 10);//Set map display bounds
}
                            
                        

  Run effects