ArcGIS for Android 100.3.0(16):RasterLayer(柵格圖層)
柵格圖層(RasterLayer)
用以載入展示移動端本地檔案、移動鑲嵌資料集、影像服務。
api地址
1.影像服務
mMapView = (MapView) findViewById(R.id.mapView);
ArcGISMap map = new ArcGISMap(Basemap.createDarkGrayCanvasVector());
mMapView.setMap(map);
// create image service raster as raster layer
final ImageServiceRaster imageServiceRaster = new ImageServiceRaster(image_service_url);
final RasterLayer rasterLayer = new RasterLayer(imageServiceRaster);
// add raster layer as map operational layer
map.getOperationalLayers().add(rasterLayer);
// zoom to the extent of the raster service
rasterLayer.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
if (rasterLayer.getLoadStatus() == LoadStatus.LOADED) {
// get the center point
Point centerPnt = imageServiceRaster.getServiceInfo().getFullExtent().getCenter();
mMapView.setViewpointCenterAsync(centerPnt, 55000000 );
}
}
});
}
2.柵格檔案
Raster raster = new Raster(Environment.getExternalStorageDirectory().getAbsolutePath() + "/xhk.tif");
// create a raster layer
final RasterLayer rasterLayer = new RasterLayer(raster);
ArcGISMap map = new ArcGISMap(Basemap.createImagery());
mMapView.setMap(map);
map.getOperationalLayers().add(rasterLayer);
// set viewpoint on the raster
rasterLayer.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
mMapView.setViewpointGeometryAsync(rasterLayer.getFullExtent(), 50);
}
});
3.GeoPackage
GeoPackage geoPackage = new GeoPackage(Environment.getExternalStorageDirectory() + "/ArcGIS/Samples/GeoPackage/AuroraCO.gpkg";
geoPackage.loadAsync();
geoPackage.addDoneLoadingListener(() -> {
if (geoPackage.getLoadStatus() == LoadStatus.LOADED) {
if (!geoPackage.getGeoPackageRasters().isEmpty()) {
// read raster images and get the first one
Raster geoPackageRaster = geoPackage.getGeoPackageRasters().get(0);
// create a layer to show the raster
RasterLayer geoPackageRasterLayer = new RasterLayer(geoPackageRaster);
// add the image as a raster layer to the map (with default symbology)
mMapView.getMap().getOperationalLayers().add(geoPackageRasterLayer);
} else {
String emptyMessage = "No rasters found in this GeoPackage!";
Toast.makeText(RasterLayerGeopackageActivity.this, emptyMessage, Toast.LENGTH_LONG).show();
Log.e(TAG, emptyMessage);
}
} else {
String error = "GeoPackage failed to load!";
Toast.makeText(RasterLayerGeopackageActivity.this, error, Toast.LENGTH_LONG).show();
Log.e(TAG, error);
}
});
4.移動鑲嵌資料集(MosaicDatasetRaster)
String rasterFilePath = "/path/to/mosaic.sqlite";
mainMapView = (MapView) findViewById(R.id.mainMapView);
ArcGISMap mainArcGISMap = new ArcGISMap(Basemap.createTopographic());
mainMapView.setMap(mainArcGISMap);
List<String> mainMosaicDatasetRasterNames = MosaicDatasetRaster.getNames(rasterFilePath);
for (String name: mainMosaicDatasetRasterNames
) {
MosaicDatasetRaster mainMosaicDatasetRaster = new MosaicDatasetRaster(urlOrPath,name);
RasterLayer mainMDRasterLayer = new RasterLayer(mainMosaicDatasetRaster);
mainArcGISMap.getOperationalLayers().add(mainMDRasterLayer);
}
5.RenderingRuleInfo(渲染規則)
用以定義如何對請求的影像進行渲染和處理。
它可以從服務中定義的名稱建立,也可以使用獲得getRenderingRuleInfos()。它可以用來構建一個RenderingRule。
通過ImageServiceRaster,獲取RenderingRuleInfo,進一步得到Rendering Rule。
下面給出官方案例:
public class RasterRenderingRuleActivity extends AppCompatActivity {
private MapView mMapView;
private ArcGISMap map;
private String image_service_url = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/CharlotteLAS/ImageServer";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_raster_rendering_rule);
mMapView = findViewById(R.id.mapView);
map = new ArcGISMap(Basemap.createStreets());
mMapView.setMap(map);
// create image service raster as raster layer and add to map
final ImageServiceRaster imageServiceRaster = new ImageServiceRaster(image_service_url);
final RasterLayer imageRasterLayer = new RasterLayer(imageServiceRaster);
map.getOperationalLayers().add(imageRasterLayer);
Spinner spinner = findViewById(R.id.spinner);
final List<String> renderRulesList = new ArrayList<>();
final ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, renderRulesList);
spinner.setAdapter(spinnerAdapter);
// zoom to the extent of the raster service
imageRasterLayer.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
if (imageRasterLayer.getLoadStatus() == LoadStatus.LOADED) {
// zoom to extent of raster
mMapView.setViewpointGeometryAsync(imageServiceRaster.getServiceInfo().getFullExtent());
// get the predefined rendering rules and add to spinner
List<RenderingRuleInfo> renderingRuleInfos = imageServiceRaster.getServiceInfo().getRenderingRuleInfos();
for (RenderingRuleInfo renderRuleInfo : renderingRuleInfos) {
String renderingRuleName = renderRuleInfo.getName();
renderRulesList.add(renderingRuleName);
// update array adapter with list update
spinnerAdapter.notifyDataSetChanged();
}
}
}
});
// listen to the spinner
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
applyRenderingRule(imageServiceRaster, position);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
Log.d("MainActivity", "Spinner nothing selected");
}
});
}
/**
* Apply a rendering rule on a Raster and add it to the map
*
* @param imageServiceRaster image service raster to apply rendering on
* @param index spinner selected position representing the rule to apply
*/
private void applyRenderingRule(ImageServiceRaster imageServiceRaster, int index) {
// clear all rasters
map.getOperationalLayers().clear();
// get the rendering rule info at the selected index
RenderingRuleInfo renderRuleInfo = imageServiceRaster.getServiceInfo().getRenderingRuleInfos().get(index);
// create a rendering rule object using the rendering rule info
RenderingRule renderingRule = new RenderingRule(renderRuleInfo);
// create a new image service raster
ImageServiceRaster appliedImageServiceRaster = new ImageServiceRaster(image_service_url);
// apply the rendering rule
appliedImageServiceRaster.setRenderingRule(renderingRule);
// create a raster layer using the image service raster
RasterLayer rasterLayer = new RasterLayer(appliedImageServiceRaster);
// add the raster layer to the map
map.getOperationalLayers().add(rasterLayer);
}
@Override
protected void onPause() {
super.onPause();
mMapView.pause();
}
@Override
protected void onResume() {
super.onResume();
mMapView.resume();
}
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.dispose();
}
}
通過Json設定渲染規則:
// create rendering rule
RenderingRule renderingRule = new RenderingRule("{\"rasterFunction\" : \"Hillshade\",\"rasterFunctionArguments\" : {\"Azimuth\" : 215.0,\"Altitude\" : 75.0,\"ZFactor\" 未完
// get a property of rendering rule
renderingRule.getRenderingRuleJson();
// set on image service raster
serviceRaster.setRenderingRule(renderingRule);
// create a raster layer
RasterLayer layer = new RasterLayer(serviceRaster);
6.RasterFunction(定義載入)
RasterFunction是針對Raster結合展現的方法進而呈現不同渲染的影像,本質上不改變源資料。
案例:
通過RasterFunction定義山體陰影,得到新的RasterLayer
/**
* RasterFunction定義載入
* RasterFunction是針對Raster結合展現的方法進而呈現不同渲染的影像,本質上不改變源資料。
*/
public class RasterFunctionServiceActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
private MapView mMapView;
private Button mRasterFunctionButton;
private String image_service_raster_url="http://sampleserver6.arcgisonline.com/arcgis/rest/services/NLCDLandCover2001/ImageServer";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_raster_function_service);
mMapView = findViewById(R.id.mapView);
mRasterFunctionButton = findViewById(R.id.rasterButton);
mRasterFunctionButton.setEnabled(false);
// create a map with the BasemapType topographic
ArcGISMap map = new ArcGISMap(Basemap.createDarkGrayCanvasVector());
final ImageServiceRaster imageServiceRaster = new ImageServiceRaster(image_service_raster_url);
final RasterLayer imageRasterLayer = new RasterLayer(imageServiceRaster);
map.getOperationalLayers().add(imageRasterLayer);
// zoom to the extent of the raster service
imageRasterLayer.addDoneLoadingListener(() -> {
if (imageRasterLayer.getLoadStatus() == LoadStatus.LOADED) {
// get the center point
Point centerPnt = imageServiceRaster.getServiceInfo().getFullExtent().getCenter();
mMapView.setViewpointCenterAsync(centerPnt, 55000000);
mRasterFunctionButton.setEnabled(true);
} else {
String error = "Error loading image raster layer: " + imageRasterLayer.getLoadError();
Log.e(TAG, error);
Toast.makeText(this, error, Toast.LENGTH_LONG).show();
}
});
// 點選按鈕:通過RasterFunction定義山體陰影,得到新的RasterLayer
mRasterFunctionButton.setOnClickListener(v -> applyRasterFunction(imageServiceRaster));
// set the map to be displayed in this view
mMapView.setMap(map);
}
private void applyRasterFunction(Raster raster) {
// 通過Json設定渲染規則
RasterFunction rasterFuntionFromJson = RasterFunction.fromJson(getString(R.string.hillshade_simplified));
// get parameter name value pairs used by hillside
RasterFunctionArguments rasterFunctionArguments = rasterFuntionFromJson.getArguments();
// get a list of raster names associated with the raster function
List<String> rasterNames = rasterFunctionArguments.getRasterNames();
rasterFunctionArguments.setRaster(rasterNames.get(0), raster);
// create raster as raster layer
raster = new Raster(rasterFuntionFromJson);
RasterLayer hillshadeLayer = new RasterLayer(raster);
mMapView.getMap().getOperationalLayers().add(hillshadeLayer);
}
@Override
protected void onPause() {
super.onPause();
mMapView.pause();
}
@Override
protected void onResume() {
super.onResume();
mMapView.resume();
}
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.dispose();
}
}
json字串:
<string name="hillshade_simplified">
{
\"raster_function_arguments\":
{
\"z_factor\":{\"double\":25.0,\"type\":\"Raster_function_variable\"},
\"slope_type\":{\"raster_slope_type\":\"none\",\"type\":\"Raster_function_variable\"},
\"azimuth\":{\"double\":315,\"type\":\"Raster_function_variable\"},
\"altitude\":{\"double\":45,\"type\":\"Raster_function_variable\"},
\"type\":\"Raster_function_arguments\",
\"raster\":{\"name\":\"raster\",\"is_raster\":true,\"type\":\"Raster_function_variable\"},
\"nbits\":{\"int\":8,\"type\":\"Raster_function_variable\"}
},
\"raster_function\":{\"type\":\"Hillshade_function\"},
\"type\":\"Raster_function_template\"
}
</string>
柵格渲染器(RasterRenderer)
RasterRenderer能夠對柵格圖層( RasterLayer )進行展示和視覺化。目前包括以下內容:
- HillshadeRenderer:山體陰影渲染
- BlendRenderer:混合渲染
- ColormapRenderer :色彩對映表渲染
- StretchRenderer:拉伸渲染
- RGBRenderer:RGB 渲染
這些渲染器官方例子中都有,有興趣的可以自己去下載,下面就來看看官方案例.
HillshadeRenderer(山體陰影渲染)
主要針對數字高程模型、單波段柵格資料,通過設定太陽的方位角和高出地平線的高度(角度或坡度),建立一個灰度級的3D高程表面。
構造方法1:
altitude:太陽高度角,預設45°
azimuth:太陽方位角,預設315°
zFactor:垂直方向的拉伸誇張程度
HillshadeRenderer(double altitude, double azimuth, double zFactor)
構造方法2:
HillshadeRenderer(double altitude, double azimuth, double zFactor, SlopeType slopeType, double pixelSizeFactor, double pixelSizePower, int outputBitDepth)
使用:
mainMapView =(MapView) findViewById(R.id.mapView);
mainMapView.setAttributionTextVisible(false);
ArcGISMap mainArcGISMap = new ArcGISMap(new Basemap());
mainMapView.setMap(mainArcGISMap);
String rasterFilePath = getResources().getString(R.string.raster_file_path);
Raster mainRasterFile = new Raster(rasterFilePath);
mainRasterLayer = new RasterLayer(mainRasterFile);
mAltitude = 45;
mAzimuth = 315;
mZFactor = 0.000016;
mSlopeType = SlopeType.NONE;
mPixelSizeFactor = 1;
mPixelSizePower = 1;
mOutputBitDepth = 8;
HillshadeRenderer hillshadeRenderer = new HillshadeRenderer(mAltitude, mAzimuth,
mZFactor, mSlopeType, mPixelSizeFactor, mPixelSizePower, mOutputBitDepth);
mainRasterLayer.setRasterRenderer(hillshadeRenderer);
mainArcGISMap.getOperationalLayers().add(mainRasterLayer);
BlendRenderer(混合渲染)
將一張山體陰影的影像(柵格Raster),混合入要渲染的原始柵格,讓原始柵格看起來具備地形陰影效果。
mainMapView =(MapView) findViewById(R.id.mapView);
mainMapView.setAttributionTextVisible(false);
ArcGISMap mainArcGISMap = new ArcGISMap(new Basemap());
mainMapView.setMap(mainArcGISMap);
String rasterFilePath = getResources().getString(R.string.raster_file_path);
Raster mainRasterFile = new Raster(rasterFilePath);
String rasterDEMFilePath = getResources().getString(R.string.elevation_file_path);
mainDEMRaster = new Raster(rasterDEMFilePath);
mainRasterLayer = new RasterLayer(mainRasterFile);
mAltitude = 45;
mAzimuth = 315;
mZFactor = 1.5;
mSlopeType = SlopeType.NONE;
//ColorRamp.PresetType不能設定為NONE,不然會報錯
mColorRampType = ColorRamp.PresetType.DEM_LIGHT;
mPixelSizeFactor = 1;
mPixelSizePower = 1;
mOutputBitDepth = 8;
ColorRamp colorRamp = new ColorRamp(mColorRampType, 800);
BlendRenderer blendRenderer = new BlendRenderer(
mainDEMRaster,
Collections.singletonList(9.0),
Collections.singletonList(255.0),
null,
null,
null,
null,
colorRamp,
mAltitude,
mAzimuth,
mZFactor,
mSlopeType,
mPixelSizeFactor,
mPixelSizePower,
mOutputBitDepth);
mainRasterLayer.setRasterRenderer(blendRenderer);
mainArcGISMap.getOperationalLayers().add(mainRasterLayer);
mainRasterLayer.loadAsync();
mainRasterLayer.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
mainMapView.setViewpointGeometryAsync(mainRasterLayer.getFullExtent(), 50);
}
});
ColormapRenderer(色彩對映表渲染)
定義使用顏色對映的渲染器。如果希望柵格圖層中的值由指定顏色表示,則可以使用此渲染器。
通過提供柵格畫素值的離散對映顏色,所有畫素匹配指定的值使用對映呈現顏色。這可以用於土地分類等任務。
private void loadRaster() {
// create a raster from a local raster file
Raster raster = new Raster(buildRasterPath());
// create a raster layer
final RasterLayer rasterLayer = new RasterLayer(raster);
// create a Map with imagery basemap
ArcGISMap map = new ArcGISMap(Basemap.createImagery());
// add the map to a map view
mMapView.setMap(map);
// add the raster as an operational layer
map.getOperationalLayers().add(rasterLayer);
// create a color map where values 0-149 are red (Color.RED) and 150-250 are yellow (Color.Yellow)
List<Integer> colors = new ArrayList<>();
for (int i = 0; i <= 250; i++) {
if (i < 150) {
colors.add(i, Color.RED);
} else {
colors.add(i, Color.YELLOW);
}
}
// create a colormap renderer
ColormapRenderer colormapRenderer = new ColormapRenderer(colors);
// set the ColormapRenderer on the RasterLayer
rasterLayer.setRasterRenderer(colormapRenderer);
// set Viewpoint on the Raster
rasterLayer.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
if (rasterLayer.getLoadStatus() == LoadStatus.LOADED) {
mMapView.setViewpointGeometryAsync(rasterLayer.getFullExtent(), 50);
} else {
String error = "RasterLayer failed to load: " + rasterLayer.getLoadError().getMessage();
Log.e(TAG, error);
Toast.makeText(ColormapRendererActivity.this, error, Toast.LENGTH_LONG).show();
}
}
});
}
private String buildRasterPath() {
// get sdcard resource name
File extStorDir = Environment.getExternalStorageDirectory();
// get the directory
String extSDCardDirName = "ArcGIS/samples/raster";
// get raster filename
String filename = "ShastaBW";
// create the full path to the raster file
return extStorDir.getAbsolutePath()
+ File.separator
+ extSDCardDirName
+ File.separator
+ filename
+ ".tif";
}
StretchRenderer(拉伸渲染)
用於以平滑漸變的顏色顯示連續的柵格像元值。使用“拉伸”渲染器來繪製單波段的連續資料。該方法非常適合於諸如影像、航空像片或高程模型等要顯示的像元值位於較大範圍的柵格資料。
mainMapView = (MapView) findViewById(R.id.mapView);
mainMapView.setAttributionTextVisible(false);
ArcGISMap mainArcGISMap = new ArcGISMap(new Basemap());
mainMapView.setMap(mainArcGISMap);
String rasterFilePath = getResources().getString(R.string.raster_file_path);
Raster mainRasterFile = new Raster(rasterFilePath);
mainRasterLayer = new RasterLayer(mainRasterFile);
mMin = 0;
mMax = 255;
mPercentClipMin = 0;
mPercentClipMax = 99;
mStdDevFactor = 1;
MinMaxStretchParameters stretchParameters = new MinMaxStretchParameters(
Collections.singletonList((double) mMin),
Collections.singletonList((double) mMax));
PercentClipStretchParameters stretcPChParameters = new PercentClipStretchParameters(mPercentClipMin, mPercentClipMax);
StretchRenderer stretchRenderer = new StretchRenderer(stretchParameters, Collections.singletonList((double) 1.5), true, null);
mainRasterLayer.setRasterRenderer(stretchRenderer);
mainArcGISMap.getOperationalLayers().add(mainRasterLayer);
mainRasterLayer.loadAsync();
mainRasterLayer.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
mainMapView.setViewpointGeometryAsync(mainRasterLayer.getFullExtent(), 50);
}
});
RGBRenderer(RGB 渲染)
RGB 渲染與拉伸渲染使用相同的方法,但前者允許以“紅、綠、藍”合成方式組合多個波段。在使用多波段柵格資料集(如衛星或航空影像)時,可以使用RGB 渲染來顯示不同的波段組合。
mainMapView = (MapView) findViewById(R.id.mapView);
mainMapView.setAttributionTextVisible(false);
ArcGISMap mainArcGISMap = new ArcGISMap(new Basemap());
mainMapView.setMap(mainArcGISMap);
String rasterFilePath = getResources().getString(R.string.raster_file_path);
Raster mainRasterFile = new Raster(rasterFilePath);
mainRasterLayer = new RasterLayer(mainRasterFile);
mMinR = 0;
mMaxR = 255;
mMinG = 0;
mMaxG = 255;
mMinB = 0;
mMaxB = 255;
mPercentClipMin = 0;
mPercentClipMax = 99;
mStdDevFactor = 1;
MinMaxStretchParameters stretchParameters = new MinMaxStretchParameters(
Arrays.asList((double) mMinR, (double) mMinG, (double) mMinB),
Arrays.asList((double) mMaxR, (double) mMaxG, (double) mMaxB));
RGBRenderer rgbRenderer = new RGBRenderer(stretchParameters, Arrays.asList(0, 1, 2), null, true);
mainRasterLayer.setRasterRenderer(rgbRenderer);
mainArcGISMap.getOperationalLayers().add(mainRasterLayer);
mainRasterLayer.loadAsync();
mainRasterLayer.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
mainMapView.setViewpointGeometryAsync(mainRasterLayer.getFullExtent(), 50);
}
});