Select to view content in your preferred language

Create Map Tile Package script: Displays in Pro, not Field Maps using WKID 3857

1764
2
Jump to solution
04-06-2022 09:58 AM
Britta_Schroeder
Occasional Contributor

Using the script below, I created map tile package (.tpkx) files from a mosaic raster for use as an offline base map in Field Maps. The .tpkx files display as expected in ArcGIS Pro and are loaded onto the iOS devices without issue. Yet, when using a map that supports other .tpkx files in the same projected coordinate system (WKID 3857), although the .tpkx files generated by the script below appear in the options for base maps, when the .tpkx is chosen from the base map list, the tiles do not appear on the map at any level.

Because the .tpkx files display as expected in ArcGIS Pro, I do not believe this issue is due to a bug in the Create Tile Package tool or in my workflow. Based on other known issues with the Create Tile Package tool, I have already checked the following:

  •  WGS84 Web Mercator (auxiliary sphere) Projected Coordinate System for the map used as the input map (WKID 3857)
  • Statistics and Pyramids exist for the mosaic used as the input raster
  • Maximum number of rasters per mosaic is equal to the number of items in the mosaic itself
  • Summary and tags in map and all layers
  • Tiling scheme is set to Online

 

# Name: CreateMapTilePackage.py
# Description: Iterate through rows in a feature to generate tile packages for each
import os
import arcpy
arcpy.env.overwriteOutput = True
p = arcpy.mp.ArcGISProject("CURRENT")
map = p.listMaps("Map")
for m in map:
    print("Name: {0}".format(m.name))
    for lyr in m.listLayers("*63K*"):
        print("Layer name: " + (lyr.name))
        with arcpy.da.SearchCursor(lyr, ['SHAPE@', 'TILE_NAME']) as cursor:
            for row in cursor:
                print('Name {0}'.format(row[1]))
                arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION","TILE_NAME = '{}'".format(row[1]))
                #print("Selected Tile: {0}".format(row[1]))
                extent = row[0].extent
                arcpy.env.extent = extent
                ##verify new extentof environment
                #print(arcpy.env.extent)
                ##verify that extent above matches extent of row
                #print('Extent of unit {}:'.format(row[1]))
                #print('XMin: {}, YMin: {}'.format(extent.XMin, extent.YMin))
                #print('XMax: {}, YMax: {}'.format(extent.XMax, extent.YMax))
                #print("Packaging {0}".format(row[1]))
                arcpy.CreateMapTilePackage_management(m, "ONLINE", "DENA_Index_{}_Topo_63K.tpkx".format(row[1]), 
                                          "JPEG","14", extent = extent)
                arcpy.management.SelectLayerByAttribute(lyr, "CLEAR_SELECTION")
                print("Selection clear")
                arcpy.env.extent = 'MAXOF'
    print("Map packaging complete")

 

 

Software information:

ArcPro 2.9.1

iPadOS 15.3.1

Field Maps v.22.10 Build 690

0 Kudos
1 Solution

Accepted Solutions
RockneRudolph
New Contributor

Pretty sure it will work if you switch to a tpk file instead of tpkx.  It's either a bug in tpkx format or the way Field Maps reads them.  Anyone know?

Here's my code that worked.  Some optional python code things: don't think you need to keep switching the environment extent or select the features. Personal preference: get data from a search cursor and put it into a list or dictionary, then iterate over that instead of doing everything inside the search cursor. 

 

 

import arcpy
arcpy.env.overwriteOutput = True

extent_dict = {}

p = arcpy.mp.ArcGISProject("CURRENT")
map_ = p.listMaps("Map")[0]
print(f"Map name: {map_.name} -- Spatial reference: {map_.spatialReference.name}")
lyrs = map_.listLayers("*63K*")

for lyr in lyrs:
    print(f"Extracting extents for Layer {lyr.name}")
    with arcpy.da.SearchCursor(lyr, ['SHAPE@', 'TILE_NAME']) as cursor:
        for row in cursor:
            extent = row[0].extent
            name = row[1]
            extent_dict.update([(name, extent)])


for name, extent in extent_dict.items():
    print(f"Generating tile package for {name} using \
        XMin: {extent.XMin} \
        YMin: {extent.YMin} \
        XMax: {extent.XMax} \
        YMax: {extent.YMax}")

    arcpy.CreateMapTilePackage_management(map_,
        "ONLINE",
        f"DENA_Index_{name}_Topo_63K.tpk",
        "JPEG",
        "14",
        package_type = "TPK",
        summary = f"Tile package for tile number {name}",
        extent = extent)

print("Done.")

 

 

 

View solution in original post

2 Replies
RockneRudolph
New Contributor

Pretty sure it will work if you switch to a tpk file instead of tpkx.  It's either a bug in tpkx format or the way Field Maps reads them.  Anyone know?

Here's my code that worked.  Some optional python code things: don't think you need to keep switching the environment extent or select the features. Personal preference: get data from a search cursor and put it into a list or dictionary, then iterate over that instead of doing everything inside the search cursor. 

 

 

import arcpy
arcpy.env.overwriteOutput = True

extent_dict = {}

p = arcpy.mp.ArcGISProject("CURRENT")
map_ = p.listMaps("Map")[0]
print(f"Map name: {map_.name} -- Spatial reference: {map_.spatialReference.name}")
lyrs = map_.listLayers("*63K*")

for lyr in lyrs:
    print(f"Extracting extents for Layer {lyr.name}")
    with arcpy.da.SearchCursor(lyr, ['SHAPE@', 'TILE_NAME']) as cursor:
        for row in cursor:
            extent = row[0].extent
            name = row[1]
            extent_dict.update([(name, extent)])


for name, extent in extent_dict.items():
    print(f"Generating tile package for {name} using \
        XMin: {extent.XMin} \
        YMin: {extent.YMin} \
        XMax: {extent.XMax} \
        YMax: {extent.YMax}")

    arcpy.CreateMapTilePackage_management(map_,
        "ONLINE",
        f"DENA_Index_{name}_Topo_63K.tpk",
        "JPEG",
        "14",
        package_type = "TPK",
        summary = f"Tile package for tile number {name}",
        extent = extent)

print("Done.")

 

 

 

Britta_Schroeder
Occasional Contributor

Thank you, Rocky! The script works exactly how I envisioned.

0 Kudos