banner
jzman

jzman

Coding、思考、自觉。
github

Explanation of celestial and terrestrial positioning information

The recent project involves the use of Baidu Maps. The project team has notified the use of Tianditu Maps as a replacement for Baidu Maps. One reason is that Tianditu Maps is built by the National Administration of Surveying, Mapping and Geoinformation of China, and companies can use its public version for development to provide related map information services. It is more authoritative than other maps. However, whether the services provided by Tianditu Maps are more authoritative and real-time than other maps cannot be determined by ordinary developers. Another reason is to reduce application costs, but I'm not sure if this goal can be achieved. After all, commercial map output capabilities are stronger than free versions. Let's start learning the Tianditu Android SDK first, and start with the following aspects:

  1. Importing the Tianditu SDK
  2. Displaying the map
  3. My location
  4. Modifying the location icon
  5. Getting location information
  6. Display effects

Importing the Tianditu SDK#

First, download the Tianditu Maps SDK and add the corresponding Jar files and so files to the libs folder. In the build.gradle file of the module, specify the directory of the so files as the libs directory, as follows:

sourceSets {
    main {
        // Specify the libs directory as the directory to search for so files
        jniLibs.srcDir 'libs'
    }
}

According to the permission configuration specified on the official website, it was found that some permissions were missing during use. The complete permission list is as follows:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

If the targetSdkVersion of the project is above 23, remember to dynamically request the relevant dangerous permissions. At this point, the Tianditu Maps SDK has been imported into the project.

Displaying the map#

First, import the MapView in the layout. The layout code is as follows:

<com.tianditu.android.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

At this point, the map can be displayed normally without any additional configuration. Of course, you can initialize some parameters related to the map. The commonly used configurations are as follows:

private void initMapView() {
    // Enable the built-in zoom controls
    mapView.setBuiltInZoomControls(true);
    // Get control of the MapView, which can be used to control and drive panning and zooming
    mMapController = mapView.getController();
    // Construct a GeoPoint with the given latitude and longitude, in microdegrees (degrees * 1E6)
    GeoPoint point = new GeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6));
    // Set the center point of the map
    mMapController.setCenter(point);
    // Set the zoom level of the map
    mMapController.setZoom(12);
}

The introduction of the Tianditu Android SDK and the display of the map are relatively easy compared to Baidu Maps and Amap.

My location#

In development, it is often necessary to locate the current location and animate from the previous location to the current location. The key class for obtaining my location is MyLocationOverlay. Through this class, it is easy to obtain my location. Since this class is a subclass of Overlay, after enabling my location, the instance of this class needs to be added to the MapView for my location to be displayed correctly. As for moving to the current location, the MapController class is used. After obtaining the map controller from the MapView, you can move to my location. The code is as follows:

// Create MyLocationOverlay
myLocationOverlay = new MyLocationOverlay(this, mapView);
// Enable compass position updates
myLocationOverlay.enableCompass();
// Enable my location
myLocationOverlay.enableMyLocation();
mapView.addOverlay(myLocationOverlay);
// Get the current location
mPoint = myLocationOverlay.getMyLocation();
// Animate to the current location
mMapController.animateTo(mPoint);

If the my location is successfully located, how can the default location icon be modified? Here is how to modify the default location icon.

Modifying the location icon#

The default location icon of Tianditu Maps is a blue dot icon. Often, there is a need to modify the location icon and the error radius. The error radius mainly displays a circle with shadows to indicate the current location's error range. The key class involved in location is MyLocationOverlay, which is a location overlay class responsible for drawing, obtaining my location, and displaying the compass. So how can the default location icon be modified? Here is a suggestion:

  1. Find the default location icon in the project path.
  2. Find the location where the default icon is set in the key class.
  3. Inherit the key class, rewrite the relevant code, and replace the original location icon with a new one.
  4. Use the new class to replace the MyLocationOverlay class.

This modification method is generally applicable to similar scenarios where the default icon needs to be modified. The key is to find the relevant class and positions and then do the replacement work. In this case, it corresponds to inheriting MyLocationOverlay, rewriting the drawMyLocation method, and replacing the corresponding icon. The key code is as follows:

@Override
protected void drawMyLocation(GL10 gl, MapView mapView, Location lastFix, GeoPoint myLocation, long when) {
    // Get screen coordinates
    Point point = new Point();
    mapView.getProjection().toPixels(myLocation,point);
    // Default accuracy
    float accuracy = getAccuracy();
    // Specify accuracy
    float accuracy = 500;
    // Get the actual error distance
    float distance = mapView.getProjection().metersToEquatorPixels(accuracy);
    AndroidJni.OpenglFillRound(point.x, point.y, (int)distance, 0, 360, 137, 170, 213, 77);
    // Create Drawable
    UtilTextureDrawable drawable = new UtilTextureDrawable(mContext, R.drawable.ic_location, BOUND_TYPE_CENTER);
    drawable.DrawTexture(gl,point,0.0F);
}

At this point, after using the custom MLocationOverlay to replace MyLocationOverlay and enabling my location, the location icon has been changed. Another way to modify the default location icon is to get the current location and use Marker to set a marker to achieve a custom location icon. It has been found that this method works fine, but the error range cannot be easily implemented. Overall, the previous method is better and can permanently solve the problem of customizing the icon.

Getting location information#

To obtain specific location information, you need to set a listener for the reverse geocoding callback result to obtain detailed address information. Set the coordinate position and start searching for the address. First, implement the reverse geocoding result listener, as follows:

/**
 * Reverse geocoding callback result listener
 */
class OnGeoResultListener implements TGeoDecode.OnGeoResultListener {

    @Override
    public void onGeoDecodeResult(TGeoAddress tGeoAddress, int errorCode) {

        if (TErrorCode.OK == errorCode) {
            // Query point related information
            String str = "Nearest POI name: " + tGeoAddress.getPoiName() + "\n";
            str += "Poi point direction: " + tGeoAddress.getPoiDirection() + "\n";
            str += "Poi point distance: " + tGeoAddress.getPoiDistance() + "\n";
            str += "Administrative region name: " + tGeoAddress.getCity() + "\n";
            str += "Full name of geographic description: " + tGeoAddress.getFullName() + "\n";
            str += "Address of the point: " + tGeoAddress.getAddress() + "\n";
            str += "Point direction: " + tGeoAddress.getAddrDirection() + "\n";
            str += "Point distance: " + tGeoAddress.getAddrDistance() + "\n";
            str += "Road name: " + tGeoAddress.getRoadName() + "\n";
            str += "Distance between the point and the nearest road: " + tGeoAddress.getRoadDistance();
            tvAddress.setText(tGeoAddress.getFullName());
            System.out.println(str);
        } else {
            System.out.println("Query error: " + errorCode);
        }
    }
}

Then, set the listener for the reverse geocoding result, as follows:

// TGeoDecode is a reverse geocoding class that returns corresponding geographic information based on the input point coordinates
TGeoDecode tGeoDecode = new TGeoDecode(new OnGeoResultListener());
tGeoDecode.search(mPoint);

If there are no problems with the previous steps, the specific location information should be correct. It's just that there is no method provided to obtain the current city name. getCity() returns the administrative region name, not the current city name. This is not user-friendly for the requirement of only locating the current city. This is the end of the introduction to Tianditu Maps.

Display effects#

Pay attention to the display of the location icon and error range before and after the two modifications. The display effect is as follows:

image

In fact, the use of maps is similar. With the above content, basic requirements can be met. Of course, there is another part in map development, which is map annotation. This part will be pushed out gradually.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.