2017-07-27 514 views
2

我的目標是創建一個Android應用程序,其下載從ArcGIS門戶地圖時連接到互聯網,然後離線使用它們創建離線地圖。我想使用服務模式,所以稍後應用程序可以具有同步功能。我遵循ArcGIS here的教程。使用ArcGIS(.mmpk地圖)

我目前被困在下載地圖部分。我期望下載的地圖位於移動地圖包(.mmpk),但是我的下載目錄有一個package.info文件,以及一個地理數據庫文件夾和.mmap文件作爲image shown here。根據我的理解,我應該有一個.mmpk文件來離線使用它們。

按照本教程的步驟,我能(1)創建離線地圖的任務(2)指定參數(3)檢查離線功能。然而,在步驟(4)生成並下載離線地圖,我預計下載的地圖將會在移動地圖包(.mmpk)但它不是;正如我上面提到的圖片所示。在步驟(5)打開並使用離線地圖,我可以在使用手動傳輸到設備中的移動地圖包(.mmpk)文件時查看離線地圖。我也嘗試打開並使用我下載的(.mmap)文件,但沒有顯示地圖。

我通過步驟全碼如下所示:

(1)創建一個脫機映射任務

// Load map from a portal item 
    final Portal portal = new Portal("http://www.arcgis.com"); 
    final PortalItem webmapItem = new PortalItem(portal, "acc027394bc84c2fb04d1ed317aac674"); 

    // Create map and add it to the view 
    myMap = new ArcGISMap(webmapItem); 
    mMapView = (MapView) findViewById(R.id.mapView); 
    mMapView.setMap(myMap); 

    // Create task and set parameters 
    final OfflineMapTask offlineMapTask = new OfflineMapTask(myMap); 

(2)指定參數

// Create default parameters 
    final ListenableFuture<GenerateOfflineMapParameters> parametersFuture = offlineMapTask.createDefaultGenerateOfflineMapParametersAsync(areaOfInterest); 
    parametersFuture.addDoneListener(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       final GenerateOfflineMapParameters parameters = parametersFuture.get(); 

       // Update the parameters if needed 
       // Limit maximum scale to 5000 but take all the scales above (use 0 as a MinScale) 
       parameters.setMaxScale(5000); 

       parameters.setIncludeBasemap(false); 

       // Set attachment options 
       parameters.setAttachmentSyncDirection(GenerateGeodatabaseParameters.AttachmentSyncDirection.UPLOAD); 
       parameters.setReturnLayerAttachmentOption(GenerateOfflineMapParameters.ReturnLayerAttachmentOption.EDITABLE_LAYERS); 

       // Request the table schema only (existing features won't be included) 
       parameters.setReturnSchemaOnlyForEditableLayers(true); 

       // Update the title to contain the region 
       parameters.getItemInfo().setTitle(parameters.getItemInfo().getTitle() + " (Central)"); 

       // Create new item info 
       final OfflineMapItemInfo itemInfo = new OfflineMapItemInfo(); 

       // Override thumbnail with the new image based on the extent 
       final ListenableFuture<Bitmap> exportImageFuture = mMapView.exportImageAsync(); 
       exportImageFuture.addDoneListener(new Runnable() { 
        @Override 
        public void run() { 
         try { 

          Bitmap mapImage = exportImageFuture.get(); 
          // Scale to thumbnail size 
          Bitmap thumbnailImage = Bitmap.createScaledBitmap(mapImage, 200, 133, false); 
          // Convert to byte[] 
          ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
          thumbnailImage.compress(Bitmap.CompressFormat.JPEG, 50, stream); 
          byte[] thumbnailBytes = stream.toByteArray(); 
          stream.close(); 

          // Set values to the itemInfo 
          itemInfo.setThumbnailData(thumbnailBytes); 
          itemInfo.setTitle("Water network (Central)"); 
          itemInfo.setSnippet(webmapItem.getSnippet()); // Copy from the source map 
          itemInfo.setDescription(webmapItem.getDescription()); // Copy from the source map 
          itemInfo.setAccessInformation(webmapItem.getAccessInformation()); // Copy from the source map 
          itemInfo.getTags().add("Water network"); 
          itemInfo.getTags().add("Data validation"); 

          // Set metadata to parameters 
          parameters.setItemInfo(itemInfo); 

         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       }); 

(3)檢查離線功能

   final ListenableFuture<OfflineMapCapabilities> offlineMapCapabilitiesFuture = 
         offlineMapTask.getOfflineMapCapabilitiesAsync(parameters); 
       offlineMapCapabilitiesFuture.addDoneListener(new Runnable() { 
        @Override 
        public void run() { 
         try { 
          OfflineMapCapabilities offlineMapCapabilities = offlineMapCapabilitiesFuture.get(); 
          if (offlineMapCapabilities.hasErrors()) { 
           // Handle possible errors with layers 
           for (java.util.Map.Entry<Layer, OfflineCapability> layerCapability : 
             offlineMapCapabilities.getLayerCapabilities().entrySet()) { 
            if (!layerCapability.getValue().isSupportsOffline()) { 
             showMessage(layerCapability.getKey().getName() + " cannot be taken offline."); 
             showMessage("Error : " + layerCapability.getValue().getError().getMessage()); 
            } 
           } 

           // Handle possible errors with tables 
           for (java.util.Map.Entry<FeatureTable, OfflineCapability> tableCapability : 
             offlineMapCapabilities.getTableCapabilities().entrySet()) { 
            if (!tableCapability.getValue().isSupportsOffline()) { 
             showMessage(tableCapability.getKey().getTableName() + " cannot be taken offline."); 
             showMessage("Error : " + tableCapability.getValue().getError().getMessage()); 
            } 
           } 
          } else { 
           // All layers and tables can be taken offline! 
           showMessage("All layers are good to go!"); 
          } 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       }); 

(4)生成和下載離線地圖

   String mExportPath = String.valueOf(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)) + File.separator + "New"; 
       showMessage(mExportPath); 

       // Create and start a job to generate the offline map 
       final GenerateOfflineMapJob generateOfflineJob = 
         offlineMapTask.generateOfflineMap(parameters, mExportPath); 

       // Show that job started 
       final ProgressBar progressBarOffline = (ProgressBar) findViewById(R.id.progressBarOffline); 
       progressBarOffline.setVisibility(View.VISIBLE); 

       generateOfflineJob.start(); 
       generateOfflineJob.addJobDoneListener(new Runnable() { 
        @Override 
        public void run() { 

         // Generate the offline map and download it 
         GenerateOfflineMapResult result = generateOfflineJob.getResult(); 

         if (!result.hasErrors()) { 

          showMessage("no error"); 
          mobileMapPackage = result.getMobileMapPackage(); 
          // Job is finished and all content was generated 
          showMessage("Map " + mobileMapPackage.getItem().getTitle() + 
            " saved to " + mobileMapPackage.getPath()); 

          // Show offline map in a MapView 
          mMapView.setMap(result.getOfflineMap()); 

          // Show that job completed 
          progressBarOffline.setVisibility(View.INVISIBLE); 
         } else { 

          showMessage("error"); 
          // Job is finished but some of the layers/tables had errors 
          if (result.getLayerErrors().size() > 0) { 
           for (java.util.Map.Entry<Layer, ArcGISRuntimeException> layerError : result.getLayerErrors().entrySet()) { 
            showMessage("Error occurred when taking " + layerError.getKey().getName() + " offline."); 
            showMessage("Error : " + layerError.getValue().getMessage()); 
           } 
          } 
          if (result.getTableErrors().size() > 0) { 
           for (java.util.Map.Entry<FeatureTable, ArcGISRuntimeException> tableError : result.getTableErrors().entrySet()) { 
            showMessage("Error occurred when taking " + tableError.getKey().getTableName() + " offline."); 
            showMessage("Error : " + tableError.getValue().getMessage()); 
           } 
          } 
          // Show that job completed 
          progressBarOffline.setVisibility(View.INVISIBLE); 
         } 
        } 
       }); 

(5)打開和使用離線地圖

// Create the mobile map package 
    final MobileMapPackage mapPackage = new MobileMapPackage(mobileMapPackage.getPath()); 
    // Load the mobile map package asynchronously 
    mapPackage.loadAsync(); 

    // Add done listener which will invoke when mobile map package has loaded 
    mapPackage.addDoneLoadingListener(new Runnable() { 
     @Override 
     public void run() { 
      // Check load status and that the mobile map package has maps 
      if(mapPackage.getLoadStatus() == LoadStatus.LOADED && mapPackage.getMaps().size() > 0){ 
       // Cdd the map from the mobile map package to the MapView 
       mMapView.setMap(mapPackage.getMaps().get(0)); 
      }else{ 
       // Log an issue if the mobile map package fails to load 
       showMessage(mapPackage.getLoadError().getMessage()); 
      } 
     } 
    }); 

showMessage()在我的代碼是顯示吐司。

public void showMessage(String message) { 
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); 
} 

我擔心如果我的.mmpk的預期是錯誤的,或者我一步出錯的地方,因爲我還沒有完全瞭解整個過程。這是我第一次使用Android中的ArcGIS地圖。我無法找到很多示例代碼進行實驗,所以非常感謝能夠幫助的人。

謝謝!

回答

0

該任務創建了一個爆炸移動地圖包,其工作原理與.mmpk文件相同。打開它,像這樣:

final MobileMapPackage mapPackage = new MobileMapPackage("/data/com.geoinfo.asmasyakirah.arcgis/files/Documents/New");

(如果你無法在那裏訪問它,你可能要產生Environment.getExternalStorageDirectory()而不是Environment.DIRECTORY_DOCUMENTS移動地圖包)。

the documentation for the MobileMapPackage constructor

創建從在t .mmpk文件或分解移動地圖包新MobileMapPackage他給了路徑。

如果您確實必須將其作爲.mmpk文件,則只需使用Android API製作zip文件並將其命名爲.mmpk而不是.zip即可。

+0

謝謝你,**爆炸的移動地圖包**描述幫助我理解我在正確的路徑(hha)上獲得所需的輸出。我將來可能會使用它。 在收到您的答案之前,我嘗試了其他的選擇;下載並使用.geodatabase文件。它的工作是好事。只是在指定參數時決定Envelope(感興趣區域)的一些錯誤,這會使我的圖層在下載後不可見。現在修復。 對於我的mmpk部分,我嘗試zip下載的文件並重命名爲.mmpk。我可以閱讀地圖,但圖層不可見。請儘快再試,謝謝! – eysdfgh

相關問題