package com.tofly.ghrq_route.base.ui;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;

import com.amap.api.maps.model.LatLng;
import com.amap.api.navi.AmapNaviType;
import com.amap.api.navi.model.NaviLatLng;
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.Geometry;
import com.esri.arcgisruntime.geometry.ImmutablePart;
import com.esri.arcgisruntime.geometry.ImmutablePartCollection;
import com.esri.arcgisruntime.geometry.Part;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.Polyline;
import com.esri.arcgisruntime.geometry.PolylineBuilder;
import com.esri.arcgisruntime.geometry.Segment;
import com.esri.arcgisruntime.layers.ArcGISTiledLayer;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.LayerList;
import com.esri.arcgisruntime.mapping.Viewpoint;
import com.esri.arcgisruntime.mapping.view.Callout;
import com.esri.arcgisruntime.mapping.view.Graphic;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.LocationDisplay;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.LineSymbol;
import com.esri.arcgisruntime.symbology.MarkerSymbol;
import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
import com.esri.arcgisruntime.symbology.TextSymbol;
import com.gaoyuan.weixinrecord.utils.PermissionHelper;
import com.google.android.material.snackbar.Snackbar;
import com.mgq.base.utils.progressdialog.ProgressManager;
import com.mgq.base.utils.toast.ToastUtil;
import com.tofly.ghrq_route.R;
import com.tofly.ghrq_route.base.BaseApp;
import com.tofly.ghrq_route.common.ui.activity.DownloadMapActivity;
import com.tofly.ghrq_route.common.ui.activity.UiSketchUpload;
import com.tofly.ghrq_route.common.ui.dialog.UiMainLayerManagerDailog;
import com.tofly.ghrq_route.common.util.AmapNavi.BaseActivity;
import com.tofly.ghrq_route.common.util.AmapNavi.SingleRouteCalculateActivity;
import com.tofly.ghrq_route.common.util.AmapNavi.WalkRouteCalculateActivity;
import com.tofly.ghrq_route.common.util.ArcgisUtils.ArcgisUtils;
import com.tofly.ghrq_route.common.util.EventBusUtil;
import com.tofly.ghrq_route.common.util.Location.LocationUtil_xu;
import com.tofly.ghrq_route.common.util.date.DateUtils;
import com.tofly.ghrq_route.common.util.file.FileUtil;
import com.tofly.ghrq_route.common.util.image.PhotoHelper;
import com.tofly.ghrq_route.common.util.net.NetUtil;
import com.tofly.ghrq_route.module.gps.GpsTool;
import com.tofly.ghrq_route.module.gps.domain.LocationGPSDataBean;
import com.tofly.ghrq_route.module.gps.domain.SignPathEvent;
import com.tofly.ghrq_route.module.map.controller.MapController;
import com.tofly.ghrq_route.module.map.interfaces.MapLoadHelper;
import com.tofly.ghrq_route.module.plan.domain.OfflinePathBean;
import com.tofly.ghrq_route.module.sketch.domain.SketchBean;
import com.tofly.ghrq_route.module.user.domain.UserBean;

import org.greenrobot.eventbus.Subscribe;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

/**
 * 带图层管理 Activity 父类
 */

public class BaseMapController {
    //最大比例尺
    public static final int MAX_SCALE = 300;
    //    最小比例尺
    public static final int MIN_SCALE = 1120000;

    public static final double DEFAULTSCALE = 5000 ; // 500000;

    /**
     * 地图显示范围
     */
    //    德阳
    public static final double XMIN1 = 639643.839792426;
    public static final double YMIN1 = 3269958.42953713;
    public static final double XMAX1 = 644114.248733244;
    public static final double YMAX1 = 3273603.336826943;

    public static final double XMIN_2000 = 104.164;
    public static final double YMIN_2000 = 30.944;
    public static final double XMAX_2000 = 104.309;
    public static final double YMAX_2000 = 31.051;
    //            成都
/*    public static final double XMIN1 = 401382.029197118;
    public static final double YMIN1 = 3394313.508322195;
    public static final double XMAX1 = 402729.753246732;
    public static final double YMAX1 = 3396401.54433908;*/

    private Context mContext;

    public ArcGISMap arcMap = null;
    public ArcgisUtils arcgisUtils;
    private MapLoadHelper mapLoadHelper;
    public MapController mapController;
    public GraphicsOverlay signLayer;

    private TextView textSketch;
    private ImageView imageRefresh;
    //private MapView mapView;

    public PhotoHelper photoHelper;

    public PermissionHelper permissionHelper;

    protected Point mLocation = null;

    protected Point mProjLoc = null;

    protected String mAddress = null;

    private boolean isMapLoaded = false;

    private GraphicsOverlay overlay;

    private MapView mapView;

    public static final String FILEPATH_KEY = "filePath";
    public static final String SCALE_KEY = "SCALE_KEY";
    public static final String CENTER_KEY = "CENTER_KEY";
    public static final String LOCATION_KEY = "LOCATION_KEY";
    public static final String ADDR_KEY = "ADDR_KEY";
    public static final String SKETCH_KEY = "sketch_bean";

    public Point getLocation() {
        return mLocation;
    }

    public void setLocation(Point mLocation) {
        this.mLocation = mLocation;
    }

    public Point getProjLoc() {
        return mProjLoc;
    }

    public void setProjLoc(Point mProjLoc) {
        this.mProjLoc = mProjLoc;
    }

    public String getAddress() {
        return mAddress;
    }

    public void setAddress(String mAddress) {
        this.mAddress = mAddress;
    }

    public boolean isMapLoaded() {
        return isMapLoaded;
    }

    public void setMapLoaded(boolean mapLoaded) {
        isMapLoaded = mapLoaded;
    }

    public ArcGISMap getArcMap() {
        return arcMap;
    }

    public void setArcMap(ArcGISMap arcMap) {
        this.arcMap = arcMap;
    }

    public void setDefaultscale(MapView mapView) {
        if (mapView != null) {
            mapView.setViewpointScaleAsync(DEFAULTSCALE);
        }
    }

    public void setMapExtent(MapView mapView){
        arcMap.setMaxScale(MAX_SCALE);
        arcMap.setMinScale(MIN_SCALE);

        // create an initial extent envelope
        //Envelope initialExtent = new Envelope(XMIN, YMIN, XMAX, YMAX, mapView.getSpatialReference());
        if (mapView != null) {
            Envelope initialExtent = new Envelope(XMIN_2000, YMIN_2000, XMAX_2000, YMAX_2000, mapView.getSpatialReference());
            // create a viewpoint from envelope
            Viewpoint viewpoint = new Viewpoint(initialExtent);
            // set initial map extent
            arcMap.setInitialViewpoint(viewpoint);
        }
/*        PointCollection collection = new PointCollection(mapView.getSpatialReference());
        collection.add(XMIN, YMIN);
        collection.add(XMAX, YMAX);
        Polygon polygon = new Polygon(collection);
        mapView.setViewpointGeometryAsync(polygon);*/
    }

    public BaseMapController(Context context, MapLoadHelper mapLoadHelper) {
        mContext = context;
        this.mapLoadHelper = mapLoadHelper;
        mapController = new MapController(context, this, mapLoadHelper);
        ArcGISRuntimeEnvironment.setLicense("LsF0ObWTcf7WkCKf");
        //ArcGISRuntime.setClientId("LsF0ObWTcf7WkCKf");

        //EventBusUtil.register(this);

        permissionHelper = new PermissionHelper(mContext);
        photoHelper = new PhotoHelper(mContext, permissionHelper);
        arcgisUtils = new ArcgisUtils(mContext);
    }

    public void loadMap(MapView mapView) {
        arcgisUtils.setMapView(mapView);
        this.mapView = mapView;
        arcMap = new ArcGISMap();
        loadAllMap(mapView);

        LocationDisplay arcgisLdm = mapView.getLocationDisplay();
        if (arcgisLdm.isStarted())
            arcgisLdm.stop();

        //setDefaultscale(mapView);
    }

    private void loadAllMap(MapView mapView) {
        arcgisUtils.clearAllMpaData();
        mapController.loadAllMap(mapView);
    }

    public void loadBaseMap(MapView mapView) {
        arcgisUtils.setMapView(mapView);
        arcMap = new ArcGISMap();
        setDefaultscale(mapView);
        arcgisUtils.clearAllMpaData();
        mapController.loadAllMap(mapView);
    }

    public final static String SIGN_PATH_UPDATE = "signPathUpdate";

    @Subscribe
    public void onGPSPathEvent(SignPathEvent signPathEvent) {
        if (SIGN_PATH_UPDATE.equals(signPathEvent.eventString)){
            Object object = signPathEvent.object;
            if (object != null && object instanceof LocationGPSDataBean) {
                MapView mapView = mapController.getMapView();
                updateSignPath((LocationGPSDataBean)object, mapView);
            }
        }
    }

    public void updateSignPath(LocationGPSDataBean locationGPSDataBean, MapView mapView){
        if (mapView != null && locationGPSDataBean != null) {
            Point point = new Point(locationGPSDataBean.getLongitude(), locationGPSDataBean.getLatitude());
            if (isSignLayerOn){
                if (signLayer == null) {
                    signLayer = new GraphicsOverlay();
                    mapView.getGraphicsOverlays().add(signLayer);
                }else {
                    int lineGraphicId = mapController.signGraphicId;
                    if (lineGraphicId > 0) {
                        Graphic graphic = signLayer.getGraphics().get(lineGraphicId);
                        if (graphic != null){
                            Polyline polyline = (Polyline) graphic.getGeometry();
                            if (polyline != null) {
                                //polyline.lineTo(point);
                                PolylineBuilder builder = new PolylineBuilder(polyline);
                                builder.addPoint(point);
                                Polyline newPolyline = builder.toGeometry();
                                graphic.setGeometry(newPolyline);
                                //signLayer.getGraphics().set(lineGraphicId, graphic);
                            }
                        }
                    }
                }
                signLayer.getGraphics().add(new Graphic(point, BaseMapController.mMarkerSymbol));
            }
        }
    }

    public void showLayoutManager(final MapView mapView) {
        //this.mapView = mapView;
        UiMainLayerManagerDailog layerManagerDailog = new UiMainLayerManagerDailog(mContext);
        layerManagerDailog.setClicklistener(new UiMainLayerManagerDailog.ClickListenerInterface() {
            @Override
            public void doOk(boolean isOnline, boolean isBaseMapOn,
                             boolean isPipeOn, boolean isSatelliteOn, boolean isSignOn) {
                if (isOnline) {
                    loadAllMap(mapView);
                }else {
                    offlineMapLoaded(mapView, isBaseMapOn, isPipeOn, isSatelliteOn, isSignOn);
                }
                isSignLayerOn = isSignOn;
            }

            @Override
            public void doCancel() {

            }
        });
        layerManagerDailog.show();
    }

    //离线地图的模式
    public enum MapMode {
        offlineMode, troubleMode, planMode, analyzeMode;

        private MapMode() {
        }
    }

    public MapMode mapFlag;//离线地图的标记
    private boolean isSignLayerOn = true;
    public void setSignLayerOn(boolean isOn) {
        isSignLayerOn = isOn;
        UiMainLayerManagerDailog.setIsSignLayerOn(isOn);
    }

    public static MarkerSymbol mMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style
            .TRIANGLE, -65536, 10 );//点的样式
    public static LineSymbol mLineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, -16777216, 3.0F);//线的样式

    public static MarkerSymbol unsignedSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, -65536, 5);

    public static MarkerSymbol signedUndoneSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, -256, 5);

    public static MarkerSymbol signedDoneSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, -12627531, 5);

//    public void addSignLayers(MapView mapView, Map<Object, LocationGPSDataBean>
//            locationGPSDataBeanMap) {
//        if (locationGPSDataBeanMap.size() > 0) {
//            if (signLayer == null) {
//                signLayer = new GraphicsLayer();
//                mapView.addLayer(signLayer);
//            } else {
//                signLayer.removeAll();
//            }
//            int index = 0;
//            Point screenPoint;
//            Polyline polyline = new Polyline();
//            Iterator<LocationGPSDataBean> iterator = locationGPSDataBeanMap.values().iterator();
//            for (locationGPSDataBeanMap.values().iterator(); iterator.hasNext(); ++index) {
//                LocationGPSDataBean next = iterator.next();
//                screenPoint = new Point(next.getLongitude(), next.getLatitude());
//                signLayer.addGraphic(new Graphic(screenPoint, mMarkerSymbol));
//                if (index == 0) {
//                    polyline.startPath(screenPoint);
//                } else {
//                    polyline.lineTo(screenPoint);
//                }
//            }
//            signLayer.addGraphic(new Graphic(polyline, this.mLineSymbol));
//            isSignLayerOn = true;
//        } else {
//            signLayer.removeAll();
//            toast("未查询到签到后的轨迹点");
//            isSignLayerOn = false;
//        }
//    }

//    public void addSignLayers() {
//        toast("此界面不显示签到点");
//    }

    public void addOtherLayers() {

    }

    public void turnToDownload(View view) {
        Snackbar downloadsb = Snackbar.make(view, "请下载管网地图", Snackbar.LENGTH_LONG);
        downloadsb.setAction("去下载", v -> {
            mContext.startActivity(new Intent(mContext, DownloadMapActivity.class));
        });
        downloadsb.show();

        UiMainLayerManagerDailog.setIsPipeLayerOn(false);
    }

    /**
     * 离线地图加载
     *
     * @param mapView
     * @param isBaseMapOn
     * @param isPipeOn
     * @param isSatelliteOn
     * @param isSignOn
     */
    private void offlineMapLoaded(MapView mapView, boolean isBaseMapOn, boolean isPipeOn, boolean isSatelliteOn, boolean isSignOn) {
        arcgisUtils.clearAllMpaData();
        //mapView.removeAll();
        if (isBaseMapOn) {
            /*已经加载过底图数据，则在地图上显示*/
            if (mapController.isLoadTpk()){
                if (tpkLayers != null && tpkLayers.size() > 0) {
                    addArcGISLocalTiledLayers(tpkLayers, mapView);
                } else if (MapController.tpkLayers != null && MapController.tpkLayers.size() >0){
                    mapController.loadTpkByOwner();
                } else {
                    ToastUtil.showToast(mContext, mContext.getString(R.string.have_no_tpk));
                    UiMainLayerManagerDailog.setIsBaseMapLayerOn(false);
                }
            }else {
                mapController.loadBasemap(mapView);
            }
        } else if (isSatelliteOn) {
            if (mapController.isLoadSatelite()){
                if (satelliteLayers != null && satelliteLayers.size() > 0) {
                    addArcGISLocalTiledLayers(satelliteLayers, mapView);
                } else if (mapController.satelliteLayers != null && mapController.satelliteLayers.size() > 0) {
                    mapController.loadSatellitesByOwner();
                } else {
                    //toast(getString(R.string.have_no_satellie));
                    UiMainLayerManagerDailog.setIsSatelliteLayerOn(false);
                }
            }else {
                mapController.loadSatelliteLayer(mapView);
            }
        }

        if (isPipeOn) {
            /*已经加载管线数据，则在地图上显示*/
            if (mapController.isLoadGeodata()){
                if (geodatabaseLayers != null && geodatabaseLayers.length != 0) {
                    //mapView.addLayers(geodatabaseLayers);
                    mapLoadHelper.loadGeodataMap(geodatabaseLayers);
                } else if (mapController.geodatabaseLayers != null
                        && mapController.geodatabaseLayers.length != 0){
//                            geodatabaseLayers = mapController.geodatabaseLayers;
//                            loadGeodataMap(geodatabaseLayers);
                    mapController.loadGeoByOwner();
                }else {
                    turnToDownload(mapView);
                    UiMainLayerManagerDailog.setIsPipeLayerOn(false);
                }
            }else {
                mapController.loadGeoDatabase();
            }
        }

        if (isSignOn) {
            if (signLayer != null /*&& !signLayer.isRecycled() */) {
                mapView.getGraphicsOverlays().add(signLayer);
                //mapView.addLayer(signLayer);
            }else {
                mapController.loadSignPathLayer();
            }
        } else {
            //signLayer.recycle();
            signLayer = null;
        }
        addOtherLayers();
    }

    private GraphicsOverlay pointOverLayer = null;
    private Polyline overPolyLine;
    private Graphic pointOverGraphic;

    /**
     * @param overPaths
     */
    public void updateOverLineGraphic(MapView mapView, List<OfflinePathBean> overPaths, Context context) {
        if (pointOverLayer == null) {
            pointOverLayer = new GraphicsOverlay();
            mapView.getGraphicsOverlays().add(pointOverLayer);
        }

        if (overPaths != null) {
            Part part = new Part(mapView.getSpatialReference());
            for (OfflinePathBean overPath : overPaths) {
                String geometry = overPath.getGeometry();
                Polyline geo = (Polyline) Geometry.fromJson(geometry, mapView.getSpatialReference());

                ImmutablePartCollection parts = geo.getParts();
                for (ImmutablePart segments : parts) {
                    for (Segment segment : segments) {
                        part.add(segment);
                    }
                }
            }
            if (overPolyLine != null) {
                ImmutablePartCollection parts = overPolyLine.getParts();
                for (ImmutablePart segments : parts) {
                    for (Segment segment : segments) {
                        part.add(segment);
                    }
                }
            }
            overPolyLine = new Polyline(part);

            int overColor = context.getResources().getColor(R.color.colorPrimary_new);

            if (pointOverGraphic == null) {
                SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, overColor, 5f);
                Graphic graphic = new Graphic(overPolyLine, lineSymbol);
                pointOverLayer.getGraphics().add(graphic);
                pointOverGraphic = graphic;
            } else {
                pointOverGraphic.setGeometry(overPolyLine);
            }
        }
    }

    public void onlineMapLoaded() {
        MapView mapView = mapController.getMapView();
        setMapExtent(mapView);
        mapController.onBaseMapLoaded();
        isSignLayerOn = UiMainLayerManagerDailog.isSignLayerOn();
        if (isSignLayerOn) {
            mapController.loadSignPathLayer();
        }
        addOtherLayers();
    }

    public void clearMapData() {
        arcgisUtils.clearAllMpaData();
    }

    public List<ArcGISTiledLayer> tpkLayers;
    public FeatureLayer[] geodatabaseLayers;
    public List<ArcGISTiledLayer> satelliteLayers;

    /**
     * 加载基础图层 切片数据图层
     * 切片数据主要用来做为底图的展示，包含渲染后的地图和地图的空间参考信息，其离线数据的格式为TPK。
     * @param tpkLayers
     * @param mapView
     */
    public void loadtpkMap(List<ArcGISTiledLayer> tpkLayers, MapView mapView) {
        if (arcMap == null)
            arcMap = new ArcGISMap();
        addArcGISLocalTiledLayers(tpkLayers, mapView);
        arcMap.loadAsync();
        arcMap.addDoneLoadingListener(() -> {
            setMapExtent(mapView);
            mapView.setMap(arcMap);
            isMapLoaded = true;
            mapController.onBaseMapLoaded();
            isSignLayerOn = UiMainLayerManagerDailog.isSignLayerOn();
            if (isSignLayerOn) {
                mapController.loadSignPathLayer();
            }
        });
    }

    /**
     * 业务图层（可由在线的要素服务（FeatureLayer）、离线的本地文件（MMPK、.geodatabase）填充)
     * @param geodatabaseLayers
     * @param mapView
     */
    public void loadGeodataMap(FeatureLayer[] geodatabaseLayers, MapView mapView) {
        //this.mapView = mapView;
        //this.geodatabaseLayers = geodatabaseLayers;
        if (0 != geodatabaseLayers.length) {
            if (UiMainLayerManagerDailog.isPipeLayerOn()){
                if (arcMap != null) {
                    LayerList layerList = arcMap.getOperationalLayers();
                    layerList.addAll(Arrays.asList(geodatabaseLayers));
                }
                //mapView.addLayers(geodatabaseLayers);
            }
        }
    }

    /**
     * 加载巡检轨迹图层
     * @param signPathLayer
     * @param mapView
     */
    public void loadSignPathLayer(GraphicsOverlay signPathLayer, MapView mapView) {
        this.signLayer = signPathLayer;
        mapView.getGraphicsOverlays().add(signPathLayer);
    }
/*
    public void loadSatelliteMap(List<ArcGISTiledLayer> satelliteLayers, MapView mapView) {
        //this.mapView = mapView;
        //this.satelliteLayers = satelliteLayers;
        if (UiMainLayerManagerDailog.isSatelliteLayerOn()) {
            addArcGISLocalTiledLayers(satelliteLayers, mapView);
        }
    }
*/

    /**
     * 添加切片图层
     * @param arcGISLocalTiledLayerList
     * @param mapView
     */
    public void addArcGISLocalTiledLayers(List<ArcGISTiledLayer> arcGISLocalTiledLayerList,
                                          MapView mapView) {
        Basemap basemap = arcMap.getBasemap();
        LayerList layerList = basemap.getBaseLayers();
        for (ArcGISTiledLayer tpkLayer : arcGISLocalTiledLayerList) {
            //mapView.addLayer(tpkLayer);
            layerList.add(tpkLayer);
        }
    }

    /**
     * 地图管线截图
     */
    public void showSketch(){
        MapView mapView = mapController.getMapView();
        if (mapView == null)
            return;

        String strLoading = mContext.getResources().getString(R.string.sketch_start_sketching);
        ProgressManager.getInstance().showProgress(mContext, null, strLoading, true);

        Bitmap bitmap = getMapViewBitmap(mapView);
        if (bitmap != null) {
            SketchTask sketchTask = new SketchTask();
            sketchTask.execute(bitmap);
        }
    }

    private static final long draft_save_ok = 0;
    private static final long draft_save_error = -1;
    private class SketchTask extends AsyncTask<Bitmap, Integer, Long> {
        private String filePath = null;
        @Override
        protected Long doInBackground(Bitmap... params) {
            Bitmap drawingMapCache = params[0];
            long result;
            //文件名
            String fileName = FileUtil.RandFileName(".png");
            String dir = FileUtil.tempFileDir();
            filePath = dir + fileName;
            if (drawingMapCache != null) {
                if (FileUtil.saveImage(drawingMapCache, fileName, true)) {
                    result = 0;
                } else {
                    result = draft_save_error;
                }
                drawingMapCache.recycle();
            } else {
                result = draft_save_error;
            }
            return result;
        }

        @Override
        protected void onPostExecute(Long aLong) {
            ProgressManager.getInstance().cancelProgress();
            if (aLong == draft_save_ok){
                if (filePath != null && !filePath.isEmpty()){
                    if (FileUtil.fileExists(filePath)){
                        startGraffitiPhoto(filePath);
                    }
                }
            }else {
                ToastUtil.showToast(mContext, "草图保存失败！");
            }
        }
    }

    private void startGraffitiPhoto(String filePath){
        MapView mapView = mapController.getMapView();

        if (mapView != null){
            photoHelper.requestSketchByFilePath(filePath, (success, errStr, pictureBean) -> {
                if (success) {
                    if (pictureBean != null) {
                        String graffitiPath = pictureBean.getFilepath();
                        gotoUiSketchUpload(graffitiPath);
                    }
                } else {
                    ToastUtil.showToast(mContext, errStr);
                }
            });
        }
    }

    private void gotoUiSketchUpload(String sketchPath){
        UserBean userBean = BaseApp.getInstance().getLoginUser();
        if (!TextUtils.isEmpty(sketchPath)) {
            MapView mapView = mapController.getMapView();
            double scale = mapView.getMapScale();

            int wkid = mapView.getMap().getSpatialReference().getWkid();
            Point centerPoint = ArcgisUtils.getMapCenter(mapView);
            String time = DateUtils.getDate();

            String sketch_id = UUID.randomUUID().toString();
            SketchBean sketches = new SketchBean();
            sketches.setId(sketch_id);
            sketches.setCreatedate(time);
            sketches.setFilepath(sketchPath);
            sketches.setScale(scale);// TODO: 2016/11/11  修改数据格式
            sketches.setUserid(userBean.getUserid());
            sketches.setWkid(wkid);
            sketches.setX(centerPoint.getX());
            sketches.setY(centerPoint.getY());
            sketches.setStatus(SketchBean.SKETCH_TASK_STATUS.SKETCH_TASK_UNEDIT.getStatus());  //状态为未编辑
            Bundle bundle = new Bundle();
            bundle.putSerializable(SketchBean.SKETCH_BEAN_KEY, sketches);
            if (mProjLoc != null) {
                LocationUtil_xu.CoordinateClass coordinate =
                        new LocationUtil_xu.CoordinateClass(mProjLoc.getX(), mProjLoc.getY());
                bundle.putSerializable(BaseMapController.LOCATION_KEY, coordinate);
            }
            bundle.putString(BaseMapController.ADDR_KEY, mAddress);
            Intent intent = new Intent(mContext, UiSketchUpload.class);
            intent.putExtras(bundle);
            mContext.startActivity(intent);
        } else {
            ToastUtil.showToast(mContext, "发生未知错误，请返回主界面！");
        }
    }

    /**
     * mapView 截图
     * @param mapView
     * @return
     */
    private Bitmap getViewBitmap(MapView mapView) {
        mapView.clearFocus();
        mapView.setPressed(false);
        // 能画缓存就返回false
        boolean willNotCache = mapView.willNotCacheDrawing();
        mapView.setWillNotCacheDrawing(false);
        int color = mapView.getDrawingCacheBackgroundColor();
        mapView.setDrawingCacheBackgroundColor(0);
        if (color != 0) {
            mapView.destroyDrawingCache();
        }
        mapView.setDrawingCacheEnabled(true);
        mapView.buildDrawingCache();
        Bitmap cacheBitmap = null;
        while (cacheBitmap == null) {
            cacheBitmap = mapView.getDrawingCache();
            /*            cacheBitmap = mapView.getDrawingMapCache(*//*mapView.getLeft(), mapView.getTop()*//*0, 0, mapView.getWidth(),
                mapView.getHeight());*/
        }
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
        // Restore the view
        mapView.destroyDrawingCache();
        mapView.setWillNotCacheDrawing(willNotCache);
        mapView.setDrawingCacheBackgroundColor(color);
        return bitmap;
    }

    /**
     * Arcgis for android 100.x截屏功能
     * */
    public Bitmap getMapViewBitmap(MapView mapView) {
        mapView.clearFocus();
        mapView.setPressed(false);
        //能画缓存就返回false
        boolean willNotCache = mapView.willNotCacheDrawing();
        mapView.setWillNotCacheDrawing(false);
        int color = mapView.getDrawingCacheBackgroundColor();
        mapView.setDrawingCacheBackgroundColor(0);
        if (color != 0) {
            mapView.destroyDrawingCache();
        }
        mapView.buildDrawingCache();
        Bitmap cacheBitmap = null;
        while(cacheBitmap == null){
            final ListenableFuture<Bitmap> export = mapView.exportImageAsync();
            try {
                cacheBitmap = export.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
        // Restore the view
        mapView.destroyDrawingCache();
        mapView.setWillNotCacheDrawing(willNotCache);
        mapView.setDrawingCacheBackgroundColor(color);
        return bitmap;
    }

    public void onDestroy() {
        EventBusUtil.unregister(this);

        if (arcgisUtils != null) {
            arcgisUtils.onDestroy();
        }

        mapController.clearTpkOwner();
        mapController.clearGeoOwner();
        mapController.clearSateOwner();
    }

    /**
     * 导航模块
     * */
    // 起点终点坐标
    private NaviLatLng mNaviStart = new NaviLatLng();
    private NaviLatLng mNaviEnd = new NaviLatLng();

    /*public void amapNaviStart(AmapNaviType naviType, LatLng ltStart, LatLng ltEnd){
        Poi start = new Poi("出发点", ltStart, "");
        Poi end = new Poi("结束点", ltEnd, "");
        AmapNaviParams params = new AmapNaviParams(start, null, end, naviType, AmapPageType.NAVI);
        params.setUseInnerVoice(true);
        AmapNaviPage.getInstance().showRouteActivity(getApplicationContext(), params, this);
    }*/

    protected void showRoutePointCallout(Point mLocation, Point geometry){
        MapView mapView = mapController.getMapView();
        View view = getCalloutFromPoint(mLocation, geometry);
        arcgisUtils.hideArcgisMapCallout();
        Callout callout = mapView.getCallout();
        callout.show(view, geometry);//显示弹出框
    }

    @SuppressLint("InflateParams")
    public View getCalloutFromPoint(Point mLocation, Point toPoint) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View rootView = inflater.inflate(R.layout.plan_route_point_callout, null);//管线详情布局
        Button btnRoute = rootView.findViewById(R.id.btn_plan_route);
        ImageView imageView = rootView.findViewById(R.id.image_callout_close);
        btnRoute.setOnClickListener(v -> onRouteBtnPressed(mLocation, toPoint));
        imageView.setOnClickListener(v -> arcgisUtils.hideArcgisMapCallout());
        return rootView;
    }

    public void onRouteBtnPressed(Point mLocation, Point toPoint) {
        if (mLocation == null) {
            ToastUtil.showToast(mContext, "未获取到当前位置信息！");
            return;
        }

        if (toPoint == null) {
            ToastUtil.showToast(mContext, "未获取到目的地位置信息！");
            return;
        }

        if (!ArcgisUtils.isWgs84Point(toPoint)) {
            toPoint = ArcgisUtils.projectLocationDefault(toPoint.getX(), toPoint.getY());
        }

        if (NetUtil.NETWORN_NONE != NetUtil.getNetworkState(mContext)) {
            showRouteAlertDialog(mLocation, toPoint);
        } else {
            ToastUtil.showToast(mContext, "暂无网络连接");
        }
    }

    /**
     * 弹窗选择 步行 驾车 导航类型
     * @param mLocation 当前地址
     * @param toPoint   目的地址
     */
    private void showRouteAlertDialog(Point mLocation, final Point toPoint) {
        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext).
                setTitle("请选择导航类型").
                setItems(new String[]{"步行", "驾车"},
                        (dialog1, i) -> {
                            if (i == 0) {
                                walkNaviAmap(mLocation, toPoint);
                            }
                            if (i == 1) {
                                driveNaviAmap(mLocation, toPoint);
                            }
                        });
        dialog.setCancelable(true);
        dialog.show();
    }

    /**
     * 驾车导航
     *  @param mLocation
     * @param toPoint
     */
    public void driveNaviAmap(Point mLocation, Point toPoint){
        Point curLocation = mLocation;
        Location location = GpsTool.getInstance().getLocationInfo();
        if (location != null){
            curLocation = ArcgisUtils.projectLocationDefault(location.getLongitude(), location.getLatitude());
        }

        if (curLocation == null){
            ToastUtil.showToast(mContext, "未获取到当前位置信息！");
            return;
        }

        if (toPoint == null){
            ToastUtil.showToast(mContext, "未获取到目的地位置信息！");
            return;
        }

        LatLng ltStart = LocationUtil_xu.wgs84togcj02(mContext, curLocation.getX(), curLocation.getY());
        LatLng ltEnd = LocationUtil_xu.wgs84togcj02(mContext, toPoint.getX(), toPoint.getY());
        if(ltStart != null && ltEnd != null){
            amapNaviRouteStart(AmapNaviType.DRIVER, ltStart, ltEnd);
        }else {
            ToastUtil.showToast(mContext, "转换终点坐标失败。");
        }
    }

    /**
     * 步行导航
     * @param mLocation
     * @param toPoint
     */
    public void walkNaviAmap(Point mLocation, Point toPoint){
        Point curLocation = mLocation;

        Location location = GpsTool.getInstance().getLocationInfo();
        if (location != null){
            curLocation = ArcgisUtils.projectLocationDefault(location.getLongitude(), location.getLatitude());
        }

        if (curLocation == null){
            ToastUtil.showToast(mContext, "未获取到当前位置信息！");
            return;
        }

        if (toPoint == null){
            ToastUtil.showToast(mContext, "未获取到目的地位置信息！");
            return;
        }

        LatLng ltStart = LocationUtil_xu.wgs84togcj02(mContext, curLocation.getX(), curLocation.getY());
        LatLng ltEnd = LocationUtil_xu.wgs84togcj02(mContext, toPoint.getX(), toPoint.getY());
        if(ltStart != null && ltEnd != null){
            amapNaviRouteStart(AmapNaviType.WALK, ltStart, ltEnd);
        }else {
            ToastUtil.showToast(mContext, "转换终点坐标失败。");
        }
    }

    /**
     * 导航开始
     * @param naviType
     * @param ltStart
     * @param ltEnd
     */
    public void amapNaviRouteStart(AmapNaviType naviType, LatLng ltStart, LatLng ltEnd){
        mNaviStart = new NaviLatLng(ltStart.latitude, ltStart.longitude);
        mNaviEnd = new NaviLatLng(ltEnd.latitude, ltEnd.longitude);

        Intent intent = new Intent();
        Bundle bundle = new Bundle();
        bundle.putParcelable(BaseActivity.KEY_START_LATLNG, mNaviStart);
        bundle.putParcelable(BaseActivity.KEY_END_LATLNG, mNaviEnd);
        intent.putExtras(bundle);

        if (naviType == AmapNaviType.WALK){
            intent.setClass(mContext, WalkRouteCalculateActivity.class);
        }else {
            intent.setClass(mContext, SingleRouteCalculateActivity.class);
        }
        mContext.startActivity(intent);
    }

/*    //计算步行路线
    private boolean calculateFootRoute() {
        boolean isSuccess = mAMapNavi.calculateWalkRoute(mNaviStart, mNaviEnd);
        if (!isSuccess) {
            toast("路线计算失败,检查参数情况");
        }
        return isSuccess;
    }

    //计算驾车路线
    private boolean calculateDriveRoute() {
        mStartPoints.clear();
        mEndPoints.clear();
        mStartPoints.add(mNaviStart);
        mEndPoints.add(mNaviEnd);

        boolean isSuccess = mAMapNavi.calculateDriveRoute(mStartPoints,
                mEndPoints, null, PathPlanningStrategy.DRIVING_DEFAULT);
        if (!isSuccess) {
            toast("路线计算失败,检查参数情况");
        }
        return isSuccess;
    }*/

    /**
     * 地址搜索模块
     * */
    private GraphicsOverlay markGraphicsLayer;//标记图层

    public void clearMarkGraphic(MapView mapView) {
        if (markGraphicsLayer != null)
            mapView.getGraphicsOverlays().remove(markGraphicsLayer);
    }

    //定位到搜索地址
    public void gotoSeaarchAddr(MapView mapView, double lng, double lat, String addr) {
        LocationUtil_xu.CoordinateClass coordinate = LocationUtil_xu.gcj02towgs84(lng, lat);
        Point projectLoc = ArcgisUtils.loctionProjectDefault(coordinate.Longtitude, coordinate.Latitude);

        displaySearchResult(mapView, projectLoc, addr);
        mapView.setViewpointCenterAsync(projectLoc, 5000);
    }

    /**
     * 定位到搜索 经纬度
     * @param mapView
     * @param lng
     * @param lat
     */
    public void gotoSearchCoordinate(MapView mapView, double lng, double lat, String addr) {
        String strlng = String.format("%.6f", lng);
        String strlat = String.format("%.6f", lat);
        if (addr == null || addr.isEmpty()) {
            addr = strlng + " , " + strlat;
        }
        Point projectLoc = new Point(lng, lat);
        displaySearchResult(mapView, projectLoc, addr);
        mapView.setViewpointCenterAsync(projectLoc, 5000);
    }

    /**
     * 在地图上显示查询到的地址信息
     */
    protected void displaySearchResult(MapView mapView, Point searchpoint, String addr) {
        if (markGraphicsLayer != null) {
            mapView.getGraphicsOverlays().remove(markGraphicsLayer);
        }

        BitmapDrawable imageLoc = (BitmapDrawable) mContext.getResources().getDrawable(R.mipmap.trouble_location);
        PictureMarkerSymbol symbolLoc = new PictureMarkerSymbol(imageLoc);
        symbolLoc.setWidth(18);
        symbolLoc.setHeight(18);
        Graphic graphic = new Graphic(searchpoint, symbolLoc);
        markGraphicsLayer = new GraphicsOverlay();
        markGraphicsLayer.getGraphics().add(graphic);

        if (addr != null && !addr.isEmpty()) {
            TextSymbol textSymbol = new TextSymbol();
            textSymbol.setText(addr);
            textSymbol.setSize(14);
            textSymbol.setColor(R.color.white);
            Graphic textGraphic = new Graphic(new Point(searchpoint.getX(), searchpoint.getY() - 0.00003), textSymbol);
            markGraphicsLayer.getGraphics().add(textGraphic);
        }

        mapView.getGraphicsOverlays().add(markGraphicsLayer);
    }

    /**
     * 导航到搜索地址
     * @param mLocation
     * @param lng
     * @param lat
     */
    public void naviSearchAddr(Point mLocation, double lng, double lat) {
        LocationUtil_xu.CoordinateClass coordinate = LocationUtil_xu.gcj02towgs84(lng, lat);
        Point toPoint = new Point(coordinate.Longtitude, coordinate.Latitude, ArcgisUtils.getWgs84Spatial());
        onRouteBtnPressed(mLocation, toPoint);
    }
}
