android 开源库osmdroid绘制点线面(比例尺,缩小放大,导航图标等)

osmdroid绘制点线面(比例尺,缩小放大,导航图标等),地图的基本用法都有。需要注意就是自已位置的图标出现,一定要有打开gps,打开gps之后,获取屏幕地图的坐标也是能获取的。这次的项目代码打包,在之前两篇的osmdroid 相关博客基础上扩展的。所以有更加全面的介绍。




1,图片介绍




这就是项目整体功能了。

2,绘制5万个点


这是 5万个点用一个图层来绘制,当然你也可以使用ondraw 一个个点换算屏幕坐标的绘制。

package com.osmdroid.sample.overlay;

import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import android.widget.Toast;

import com.osmdroid.sample.util.BaseSampleFragment;

import org.osmdroid.api.IGeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.simplefastpoint.LabelledGeoPoint;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlayOptions;
import org.osmdroid.views.overlay.simplefastpoint.SimplePointTheme;

import java.util.ArrayList;
import java.util.List;

/**
 * Example of SimpleFastPointOverlay
 * Created by Miguel Porto on 12-11-2016.
 */

public class SampleSimpleFastPointOverlay extends BaseSampleFragment {

    @Override
    public String getSampleTitle() {
        return "Simple Fast Point Overlay with 10k points";
    }

    @Override
    protected void addOverlays() {
        super.addOverlays();
        // create 10k labelled points
        // in most cases, there will be no problems of displaying >100k points, feel free to try
        List<IGeoPoint> points = new ArrayList<>();
        for (int i = 0; i < 50000; i++) {
            points.add(new LabelledGeoPoint(37 + Math.random() * 5, -8 + Math.random() * 5
                    , "Point #" + i));
        }

        // wrap them in a theme
        SimplePointTheme pt = new SimplePointTheme(points, true);

        // create label style
        Paint textStyle = new Paint();
        textStyle.setStyle(Paint.Style.FILL);
        textStyle.setColor(Color.parseColor("#0000ff"));
        textStyle.setTextAlign(Paint.Align.CENTER);
        textStyle.setTextSize(24);

        // set some visual options for the overlay
        // we use here MAXIMUM_OPTIMIZATION algorithm, which works well with >100k points
        SimpleFastPointOverlayOptions opt = SimpleFastPointOverlayOptions.getDefaultStyle()
                .setAlgorithm(SimpleFastPointOverlayOptions.RenderingAlgorithm.MAXIMUM_OPTIMIZATION)
                .setRadius(7).setIsClickable(true).setCellSize(15).setTextStyle(textStyle);

        // create the overlay with the theme
        final SimpleFastPointOverlay sfpo = new SimpleFastPointOverlay(pt, opt);

        // onClick callback
        sfpo.setOnClickListener(new SimpleFastPointOverlay.OnClickListener() {
            @Override
            public void onClick(SimpleFastPointOverlay.PointAdapter points, Integer point) {
                Toast.makeText(mMapView.getContext()
                        , "You clicked " + ((LabelledGeoPoint) points.get(point)).getLabel()
                        , Toast.LENGTH_SHORT).show();
            }
        });

        // add overlay
        mMapView.getOverlays().add(sfpo);

        // zoom to its bounding box
        mMapView.addOnFirstLayoutListener(new MapView.OnFirstLayoutListener() {

            @Override
            public void onFirstLayout(View v, int left, int top, int right, int bottom) {
                if(mMapView != null && mMapView.getController() != null) {
                    mMapView.getController().zoomTo(6);
                    mMapView.zoomToBoundingBox(sfpo.getBoundingBox(), true);
                }

            }
        });

    }

}


另外一种绘制的形式

package com.osmdroid.sample.overlay;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;

import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
import org.osmdroid.views.overlay.Overlay;

/**
 * 自定义绘制的地图坐标
 */
public class CustomPointOverlay extends Overlay {

    private final Point mMapCoordsProjected = new Point();
    private final Point mMapCoordsTranslated = new Point();
    protected Paint mCirclePaint = new Paint();

    public CustomPointOverlay() {
    }

    static CustomPointOverlay mGisOverlay = null;

    public static CustomPointOverlay GetInstance() {
        if (mGisOverlay == null) {
            synchronized (CustomPointOverlay.class) {
                if (mGisOverlay == null) {
                    mGisOverlay = new CustomPointOverlay();
                }
            }
        }
        return mGisOverlay;
    }

    @Override
    public void draw(Canvas canvas, MapView mapView, boolean shadow) {

        //经纬度坐标到屏幕坐标的转换
        mapView.getProjection().toProjectedPixels(23.12658183, 113.365588756, mMapCoordsProjected);
        Projection pj = mapView.getProjection();
        pj.toPixelsFromProjected(mMapCoordsProjected, mMapCoordsTranslated);

//            final float radius = lastFix.getAccuracy()
//                    / (float) TileSystem.GroundResolution(lastFix.getLatitude(),
//                    mapView.getZoomLevel());
        final float radius = 10L;
        mCirclePaint.setColor(Color.BLUE);
        mCirclePaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(mMapCoordsTranslated.x, mMapCoordsTranslated.y, radius, mCirclePaint);
    }
}



3,绘制线


绘制线也是一样啦。使用这个类就行,Polyline

      // create 10k labelled points
        // in most cases, there will be no problems of displaying >100k points, feel free to try
        List<org.osmdroid.util.GeoPoint> points = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            points.add(new GeoPoint(37 + Math.random() * 5, -8 + Math.random() * 5, 0));
        }

        //随机产生的1000个点并连成线
        if(points.size()>0){
            org.osmdroid.views.overlay.Polyline Polyline=new org.osmdroid.views.overlay.Polyline();
            Polyline.setWidth(2);
            Polyline.setColor(0xFF1B7BCD);
            Polyline.setPoints(points);
            mapView.getOverlays().add(Polyline);
        }

        //计算边界值,定位边界
       final BoundingBox box = new BoundingBox(37,-8,42,-3);
        // zoom to its bounding box
        mapView.addOnFirstLayoutListener(new MapView.OnFirstLayoutListener() {

            @Override
            public void onFirstLayout(View v, int left, int top, int right, int bottom) {
                if(mapView != null && mapView.getController() != null) {
                    mapView.getController().zoomTo(6);
                    mapView.zoomToBoundingBox(box, true);
                }

            }
        });

    }

    //如果线的绘制,要实时绘制,可采用类似格网绘图,及时地图增加移动,放大,缩小里面监听
    //进行图层的重绘


4,绘制面


使用 polygon

        // create 10k labelled points
        // in most cases, there will be no problems of displaying >100k points, feel free to try
        List<GeoPoint> points = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            points.add(new GeoPoint(37 + Math.random() * 5, -8 + Math.random() * 5, 0));
        }

        //随机产生的1000个点并连成面
        if(points.size()>0){
            org.osmdroid.views.overlay.Polygon polygon=new org.osmdroid.views.overlay.Polygon();
            polygon.setStrokeWidth(1);
            polygon.setFillColor(0x8032B5EB);
            polygon.setStrokeColor(Color.BLUE);
            polygon.setPoints(points);
            mapView.getOverlays().add(polygon);
        }

        //计算边界值,定位边界
       final BoundingBox box = new BoundingBox(37,-8,42,-3);
        // zoom to its bounding box
        mapView.addOnFirstLayoutListener(new MapView.OnFirstLayoutListener() {

            @Override
            public void onFirstLayout(View v, int left, int top, int right, int bottom) {
                if(mapView != null && mapView.getController() != null) {
                    mapView.getController().zoomTo(6);
                    mapView.zoomToBoundingBox(box, true);
                }

            }
        });


5,基本配置,比例尺,缩小,放大


package com.osmdroid.sample;

import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Toast;

import org.osmdroid.api.IGeoPoint;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
import org.osmdroid.views.overlay.simplefastpoint.LabelledGeoPoint;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlayOptions;
import org.osmdroid.views.overlay.simplefastpoint.SimplePointTheme;

import java.util.ArrayList;
import java.util.List;

public class BasicMapTestActivity extends AppCompatActivity implements View.OnClickListener {

    private MapView mapView;
    //地图旋转
    private RotationGestureOverlay mRotationGestureOverlay;
    //比例尺
    private ScaleBarOverlay mScaleBarOverlay;
    //指南针方向
    private CompassOverlay mCompassOverlay = null;
    //设置导航图标的位置
    private MyLocationNewOverlay mLocationOverlay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basic_test);

        initView();
    }

    private void initView() {

        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
        findViewById(R.id.button3).setOnClickListener(this);
        findViewById(R.id.button4).setOnClickListener(this);

        mapView = (MapView) findViewById(R.id.mymapview);
        mapView.setDrawingCacheEnabled(true);
        mapView.setMaxZoomLevel(20);
        mapView.setMinZoomLevel(6);
        mapView.getController().setZoom(12);
        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setUseDataConnection(true);
        mapView.setMultiTouchControls(true);// 触控放大缩小
        //是否显示地图数据源
        mapView.getOverlayManager().getTilesOverlay().setEnabled(true);


        //地图自由旋转
        mRotationGestureOverlay = new RotationGestureOverlay(mapView);
        mRotationGestureOverlay.setEnabled(true);
        mapView.getOverlays().add(this.mRotationGestureOverlay);

        //比例尺配置
        final DisplayMetrics dm = getResources().getDisplayMetrics();
        mScaleBarOverlay = new ScaleBarOverlay(mapView);
        mScaleBarOverlay.setCentred(true);
        mScaleBarOverlay.setAlignBottom(true); //底部显示
        mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 5, 80);
        mapView.getOverlays().add(this.mScaleBarOverlay);

        //指南针方向
        mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
                mapView);
        mCompassOverlay.enableCompass();
        mapView.getOverlays().add(this.mCompassOverlay);

        //设置导航图标
        this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this),
                mapView);
        mapView.getOverlays().add(this.mLocationOverlay);
        mLocationOverlay.enableMyLocation();  //设置可视

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:
                //定位当前的位置,并设置缩放级别
                mapView.getController().setZoom(18);
                mapView.getController().setCenter(new GeoPoint(23.12648183, 113.365548756));
                break;
            case R.id.button2: //绘制点
                List<IGeoPoint> points = new ArrayList<>();
                points.add(new LabelledGeoPoint(23.12658183, 113.365588756 , "Point #" + 1));
                points.add(new LabelledGeoPoint(23.12647183, 113.365558756 , "Point #" + 2));
                // wrap them in a theme
                SimplePointTheme pt = new SimplePointTheme(points, true);

                // create label style
                Paint textStyle = new Paint();
                textStyle.setStyle(Paint.Style.FILL);
                textStyle.setColor(Color.parseColor("#0000ff"));
                textStyle.setTextAlign(Paint.Align.CENTER);
                textStyle.setTextSize(24);

                // set some visual options for the overlay
                // we use here MAXIMUM_OPTIMIZATION algorithm, which works well with >100k points
                SimpleFastPointOverlayOptions opt = SimpleFastPointOverlayOptions.getDefaultStyle()
                        .setAlgorithm(SimpleFastPointOverlayOptions.RenderingAlgorithm.MAXIMUM_OPTIMIZATION)
                        .setRadius(7).setIsClickable(true).setCellSize(15).setTextStyle(textStyle);

                // create the overlay with the theme
                final SimpleFastPointOverlay sfpo = new SimpleFastPointOverlay(pt, opt);

                // onClick callback
                sfpo.setOnClickListener(new SimpleFastPointOverlay.OnClickListener() {
                    @Override
                    public void onClick(SimpleFastPointOverlay.PointAdapter points, Integer point) {
                        Toast.makeText(mapView.getContext()
                                , "You clicked " + ((LabelledGeoPoint) points.get(point)).getLabel()
                                , Toast.LENGTH_SHORT).show();
                    }
                });

                // add overlay
                mapView.getOverlays().add(sfpo);
                break;
            case R.id.button3://缩小
                mapView.getController().zoomOut();
                break;
            case R.id.button4://放大
                mapView.getController().zoomIn();
                break;

        }
    }

    @Override
    public void onPause() {
        this.mLocationOverlay.disableMyLocation();
        super.onPause();
    }


    @Override
    public void onResume() {
        super.onResume();
    }
}

package com.osmdroid.sample;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.View;

import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;

public class BasicMapTestActivity3 extends AppCompatActivity implements View.OnClickListener ,LocationListener {

    private MapView mapView;
    //地图旋转
    private RotationGestureOverlay mRotationGestureOverlay;
    //比例尺
    private ScaleBarOverlay mScaleBarOverlay;
    //指南针方向
    private CompassOverlay mCompassOverlay = null;
    //设置导航图标的位置
    private MyLocationNewOverlay mLocationOverlay;
    private LocationManager lm;
    private Location currentLocation = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basic_test_3);

        initView();
    }

    private void initView() {

        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);

        mapView = (MapView) findViewById(R.id.mymapview);
        mapView.setDrawingCacheEnabled(true);
        mapView.setMaxZoomLevel(20);
        mapView.setMinZoomLevel(6);
        mapView.getController().setZoom(12);
        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setUseDataConnection(true);
        mapView.setMultiTouchControls(true);// 触控放大缩小
        //是否显示地图数据源
        mapView.getOverlayManager().getTilesOverlay().setEnabled(true);


        //地图自由旋转
        mRotationGestureOverlay = new RotationGestureOverlay(mapView);
        mRotationGestureOverlay.setEnabled(true);
        mapView.getOverlays().add(this.mRotationGestureOverlay);

        //比例尺配置
        final DisplayMetrics dm = getResources().getDisplayMetrics();
        mScaleBarOverlay = new ScaleBarOverlay(mapView);
        mScaleBarOverlay.setCentred(true);
        mScaleBarOverlay.setAlignBottom(true); //底部显示
        mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 5, 80);
        mapView.getOverlays().add(this.mScaleBarOverlay);

        //指南针方向
        mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
                mapView);
        mCompassOverlay.enableCompass();
        mapView.getOverlays().add(this.mCompassOverlay);

        //设置导航图标
        this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this),
                mapView);
        mapView.getOverlays().add(this.mLocationOverlay);
        mLocationOverlay.enableMyLocation();  //设置可视
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:
                if (currentLocation != null) {
                    GeoPoint myPosition = new GeoPoint(currentLocation.getLatitude(), currentLocation.getLongitude());
                    mapView.getController().animateTo(myPosition);
                }
                break;
            case R.id.button2:
                if (!mLocationOverlay.isFollowLocationEnabled()) {
                    mLocationOverlay.enableFollowLocation();
                } else {
                    mLocationOverlay.disableFollowLocation();
                }
                break;

        }
    }

    @Override
    public void onLocationChanged(Location location) {
        currentLocation=location;
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onPause() {
        super.onPause();
        try{
            lm.removeUpdates(this);
        }catch (Exception ex){}

        mCompassOverlay.disableCompass();
        mLocationOverlay.disableFollowLocation();
        mLocationOverlay.disableMyLocation();
        mScaleBarOverlay.enableScaleBar();
    }

    @Override
    public void onResume(){
        super.onResume();
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        try{
            //this fails on AVD 19s, even with the appcompat check, says no provided named gps is available
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0l,0f,this);
        }catch (Exception ex){}

        try{
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0l,0f,this);
        }catch (Exception ex){}

        mLocationOverlay.enableFollowLocation();
        mLocationOverlay.enableMyLocation();
        mScaleBarOverlay.disableScaleBar();
    }
}


package com.osmdroid.sample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import com.osmdroid.sample.overlay.CustomPointOverlay;
import com.osmdroid.sample.util.SomeDataMapManger;

import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;

public class BasicMapTestActivity2 extends AppCompatActivity implements View.OnClickListener {

    private MapView mapView;
    //地图旋转
    private RotationGestureOverlay mRotationGestureOverlay;
    //比例尺
    private ScaleBarOverlay mScaleBarOverlay;
    //指南针方向
    private CompassOverlay mCompassOverlay = null;
    //设置导航图标的位置
    private MyLocationNewOverlay mLocationOverlay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basic_test_2);

        initView();
    }

    private void initView() {

        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
        findViewById(R.id.button3).setOnClickListener(this);
        findViewById(R.id.button4).setOnClickListener(this);

        mapView = (MapView) findViewById(R.id.mymapview);
        mapView.setDrawingCacheEnabled(true);
        mapView.setMaxZoomLevel(20);
        mapView.setMinZoomLevel(6);
        mapView.getController().setZoom(12);
        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setUseDataConnection(true);
        mapView.setMultiTouchControls(true);// 触控放大缩小
        //是否显示地图数据源
        mapView.getOverlayManager().getTilesOverlay().setEnabled(true);


        //地图自由旋转
        mRotationGestureOverlay = new RotationGestureOverlay(mapView);
        mRotationGestureOverlay.setEnabled(true);
        mapView.getOverlays().add(this.mRotationGestureOverlay);

        //比例尺配置
        final DisplayMetrics dm = getResources().getDisplayMetrics();
        mScaleBarOverlay = new ScaleBarOverlay(mapView);
        mScaleBarOverlay.setCentred(true);
        mScaleBarOverlay.setAlignBottom(true); //底部显示
        mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 5, 80);
        mapView.getOverlays().add(this.mScaleBarOverlay);

        //指南针方向
        mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
                mapView);
        mCompassOverlay.enableCompass();
        mapView.getOverlays().add(this.mCompassOverlay);

        //设置导航图标
        this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this),
                mapView);
        mapView.getOverlays().add(this.mLocationOverlay);
        mLocationOverlay.enableMyLocation();  //设置可视
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:
                //定位当前的位置,并设置缩放级别
                mapView.getController().setZoom(18);
                mapView.getController().setCenter(new GeoPoint(23.12648183, 113.365548756));
                break;
            case R.id.button2: //绘制点
                // add overlay
                mapView.getOverlays().add(CustomPointOverlay.GetInstance());
                break;
            case R.id.button3://屏幕点击的坐标
                //这个功能的使用,需要打开gps,就是说gps有数据
                MyLocationOverlayWithClick overlay = new MyLocationOverlayWithClick(mapView);
                overlay.enableFollowLocation();
                overlay.enableMyLocation();
                mapView.getOverlayManager().add(overlay);
                break;
            case R.id.button4:
                SomeDataMapManger.initGeoJsonData(mapView,this);
                mapView.getController().setZoom(12);
                mapView.getController().setCenter(new GeoPoint(23.12648183, 113.365548756));
                break;

        }
    }

    public static class MyLocationOverlayWithClick extends MyLocationNewOverlay{

        public MyLocationOverlayWithClick(MapView mapView) {
            super(mapView);
        }
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e, MapView map) {
            if (getLastFix() != null)
                Toast.makeText(map.getContext(), "Tap! I am at " + getLastFix().getLatitude() + "," + getLastFix().getLongitude(), Toast.LENGTH_LONG).show();
            return true;

        }
    }

    @Override
    public void onPause() {
        this.mLocationOverlay.disableMyLocation();
        super.onPause();
    }


    @Override
    public void onResume() {
        super.onResume();
    }
}



  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值