BLOG
|
I am releasing the 1.1.1 version of an ArcGIS Pro Search Tool for Riverside County that in this release includes eight (8) of the Search options available in the ArcMap version posted in my Blog here. The Searches include Search by: Street Intersection APN (Assessors Parcel Number) PLUS Case (Planning and Land Use System) Assessors Subdivision Name/Number or Assessors Recorders Type Book/Page Survey Map Subdivision Name/Number or Survey Map Recorders Type Book/Page. Township, Range and Section(s) (Released - 9/28/2022) Before installing the Add-In, if you have installed any previous version of the Add-In you need to uninstall the prior version first. Open ArcGIS Pro and open the Project Settings page by doing one of the following:. Before opening an ArcGIS Pro project click the Setting button in the lower left-hand corner of the screen: After opening and ArcGIS Pro project click the Project tab in the upper left-hand corner of the screen: Click the Add-In Manager menu item on the left hand side of the Project Setting page Click on the RivCoSearchForms Add-In in the list of My Add-Ins You can verify the version is out of date by reviewing the Date and Version information prior to removing the Add-In Click on the Delete this Add-In button at the bottom right-hand corner of the screen The Add-In will still appear in the list of My Add-Ins until you close ArcGIS Pro, but it will say it is Deleted: After removing the Add-In you must close ArcGIS Pro before you install the new Add-In.. To Install the Add-In download the attached RivCoSearchForms.zip file. Extract and double-click the RivCoSearchForms.esriAddIInX file. Press the Install Add-In button on the Esri ArcGIS Add-In Installation Utility dialog. The press the OK button on the Installation succeeded notification Esri ArcGIS Add-In Installation Utility dialog. Open ArcGIS Pro and open or start a project or you can use the "Start without a template" option. An Add-In tab will have been added to your project, which you can use to choose the Search Option you want and press the cat face Search button to open the search dialog. Open or create a Map or 2D Layout in your project prior to using the cat face search tool. The search tool will verify that your current active map has the layers the tool requires. If necessary it will add them to the map provided that the tool is able to create a Database Connection to the SQL Server Database Platform using the RCIT-19GISP01 Instance with Operating System authentication using the GDB_PUB Database. If you cannot directly connect to Riverside County's GIS data server, but have obtained copies of the appropriate Riverside County Feature Classes in your own geodatabase, you can create the necessary layers by adding the following feature classes to your map and renaming the layer it creates with the layer name shown below: Feature Class Name - Layer Name CENTERLINE_INTERSECTIONS - Search Intersections ADDRESS_POINTS - Search Address Points PARCELS_CONDOS_CREST_VW (or PARCELS_CREST) - Search Parcels PLUS_ACTIVITIES_MODIFIED (or PLUS_ACTIVITIES) - Search PLUS Cases RECORDED_MAPS - Search Survey Maps ROADBOOK_PAGE_INDEX - Search Road Book Page SECTIONS - Search Sections ADDING THE SEARCH TOOL ADD-IN BUTTON AND COMBOBOX TO THE QUICK ACCESS TOOLBAR For easy access to the tool you can add the Search button and combobox for search options to the Quick Access toolbar as a onetime set up. Do the following: Dropdown the Customize Quick Access Toolbar menu as shown and press the Customize the Ribbon option. In the Options dialog scroll to the bottom of the list on the left side of the dialog and press the Quick Access Toolbar option. In the Customize the Ribbon combobox in the Options dialog choose All Commands Type search into the textbox dropdown and choose the Open Search Choice button and press the Add button and then choose the Search (Extended Caption) combobox and press the Add button. The list of tools should look like the items shown below and press the OK button The Quick Access Toolbar should now look like this. Choose the search you want in the dropdown and press the Cat button to launch the search dialog. If you have any questions, please post them here. This Blog will be updated as I release expanded or updated versions of the Search Tools and the date time of each revision publication will be added to the list at the bottom of this blog post. Originally published version 1.0 by Richard Fairhurst on September 20, 2022 at 4:07 PM PST. Updated the Add-In zip file to make improvements to the validations performed in response to user data entry in the APN Search dialog. Published by Richard Fairhurst on September 21, 2022 at 9:30 AM PST. Updated the Add-In zip file to version 1.1 to add a new Township, Range and Section(s) Search dialog option. Published by Richard Fairhurst on September 28, 2022 at 10:38 AM PST. Updated the Add-In zip file to version 1.1.1 to change label placement properties of the Standard Label Engine to label each feature part when the Search layers are added to the map. Published by Richard Fairhurst on October 2, 2022 at 4:45 PM PST.
... View more
09-20-2022
04:12 PM
|
5
|
2
|
1328
|
IDEA
|
@ChrisFoxI had never tried the SQL syntax you outlined, but this expression does work in ArcMap and ArcGIS Pro for related data in the same geodatabase. This syntax is only briefly discussed in the Subqueries section of the SQL reference for query expressions used in ArcGIS website. That section doesn't include an example that was quite as clear or useful to me as the one you have given. I frankly would like to see your example added to that section, since if it had been there years ago I would have been much more likely to see the usefulness of this approach and not had to develop some of the workarounds I came up with. Your example works for file geodatabases as well, despite the warning that file geodatabases only offer limited support for subqueries. The Subqueries section basically says that help for using them is specific to the DBMS documentation of my enterprise geodatabase. Since I've mostly worked with file geodatabases that limitation warning had kept me from even trying to figure out or use Subqueries, but based on the example you have outlined I believe I actually now have a use for them. Thanks.
... View more
09-15-2022
02:40 PM
|
0
|
0
|
1008
|
POST
|
I also figured out how to implement a property that can set the IsSelected property of the ListBoxItems of a ListBox so that it supports a TwoWay update when the Selection Mode is set to Extended and it does not have to be passed as a CommandParameter to an ICommand button. I found that the Extended SelectionMode only mostly worked properly when I included the ListBox parameter for VirtualizingStackPanel.IsVirtualizing="False" along with setting the SelectionMode="Extended". It does not appear to trigger a notification when the user actually extends their multiselection in the ListBox, so as far as I can tell the evaluation or programmatic use of the ListBox IsSelected property has to be triggered by Methods and Actions you design in your code. In this example code I am presenting a list of Lot numbers so I made my ItemSource binding to an ObservableCollection called Lots. This ObservableCollection contains ListBoxItems based on a custom class called LotSelector. I had to set up an ItemTemplate for the ListBox so the list would display the Item property of the LotSelector custom class in the ListBox and an ItemContainerStyle of ListBoxItems that would assign the IsSelected property of each ListBoxItem to the IsSelected property of my LotSelector custom class. Here is the xaml for the ListBox: <ListBox x:Name="lbxLots" VirtualizingStackPanel.IsVirtualizing="False" SelectionMode="Extended" ItemsSource="{Binding Lots, Mode=TwoWay}" SelectedItem="{Binding SelectedLot}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Item}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox> I then added a Class Item to my project named LotSelector and defined two classes in the file. The first class is named LotSelector and stores the values and IsSelected state of each ListBoxItem. The second class is named LotItemComparer based on the IComparer class so that the LotSelector instances could be sorted and kept unique using a SortedSet<LotSelector> ViewModel property. Here is the LotSelector.cs file code: using System;
using System.Collections.Generic;
using ArcGIS.Desktop.Framework.Contracts;
namespace RivCoSearchForms
{
public class LotSelector : PropertyChangedBase
{
private string _item;
public String Item
{
get { return _item; }
set
{
_item = value;
NotifyPropertyChanged(() => Item);
}
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
NotifyPropertyChanged(() => IsSelected);
}
}
}
public class LotItemComparer : IComparer<LotSelector>
{
public int Compare(LotSelector x, LotSelector y)
{
// TODO: Handle x or y being null, or them not having Items
return x.Item.CompareTo(y.Item);
}
}
} For the ViewModel I added standard code for my Lots ObservableCollection<LotSelector> property for the ListBox ItemSource and a SelectedLot string property for the SelectedItem property of the ListBox. I also added a SortedSet<LotSelector> private property of the ViewModel to ensure the Lots were distinct and sorted and could be manipulated on the MTC thread. I have included a Command implementation to show how the ListBox could be populated based on the Lot data in a Layer. (I tried to simplify the code of the Command from a more complex version and have not tested it, so the Command code may not run correctly and need correction.) Here is the ViewModel code: private ObservableCollection<LotSelector> _lots = new ObservableCollection<LotSelector>();
public ObservableCollection<LotSelector> Lots
{
get { return _lots; }
set
{
SetProperty(ref _lots, value, () => Lots);
}
}
private string _selectedLot;
public string SelectedLot
{
get { return _selectedLot; }
set
{
SetProperty(ref _selectedLot, value, () => SelectedLot);
// Blank out Book, Page list and text block
Message = null;
}
}
private SortedSet<LotSelector> ListLotsSelected;
public ICommand CmdCancel => new RelayCommand((proWindow) =>
{
// TODO: set dialog result and close the window
(proWindow as ProWindow).DialogResult = false;
(proWindow as ProWindow).Close();
}, () => true);
public ICommand CmdListLotsInLayer => new RelayCommand(async (proWindow) =>
{
ListLotsSelected = new SortedSet<LotSelector>(new LotItemComparer());
// Get the Active Mapview
var ActMap = MapView.Active;
// Get the search layer from its name
var fLayer = ActMap.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name.Equals("Search Lot Layer"));
// If layer exists proceed
if (fLayer != null)
{
// Set up a Queued Task for map changes
int iCount = await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
// Execute a Search on the layer
using (RowCursor RecMapCursor = fLayer.Search())
{
int cnt = 0;
// Iterate the found cursor rows
while (RecMapCursor.MoveNext())
{
// Get current row as a feature
using (Feature feature = (Feature)RecMapCursor.Current)
{
// Get the APN value of the feature
LotSelector Lot = new LotSelector();
int number;
bool success = int.TryParse(feature[LotField].ToString(), out number);
if (success)
{
Lot.Item = feature[LotField].ToString().PadLeft(4);
}
else
{
Lot.Item = feature[LotField].ToString();
}
// Set the IsSelected property to select the ListBoxItem
Lot.IsSelected = true;
// Update the ListLotsSelected parameter
ListLotsSelected.Add(Lot);
cnt += 1;
}
}
return cnt;
}
});
if (iCount > 0)
{
Lots.Clear();
foreach (LotSelector _Lot in ListLotsSelected)
{
Lots.Add(_Lot);
}
}
}
}, () => true);
... View more
09-14-2022
06:37 PM
|
0
|
0
|
6125
|
POST
|
I figured out the answer. Here is the code I came up with: var ActMap = MapView.Active;
MapView mapView = ActMap;
Camera camera = mapView.Camera;
double scaleFt = camera.Scale/12; // Convert inches to feet
ScaleBar alternatingScaleBar = lyt.FindElement("Alternating Scale Bar") as ScaleBar;
if (alternatingScaleBar != null)
{
CIMDoubleFillScaleBar scaleBarDef = alternatingScaleBar.GetDefinition() as CIMDoubleFillScaleBar;
if (scaleFt <= 4000)
{
scaleBarDef.UnitLabel = "Ft";
string unitJsonFt = "{\"uwkid\":9002}";
var unitFt = ArcGIS.Core.Geometry.Unit.CreateFromJson(unitJsonFt);
scaleBarDef.Units = unitFt;
}
else
{
scaleBarDef.UnitLabel = "Mi";
string unitJsonMi = "{\"uwkid\":9093}";
var unitMi = ArcGIS.Core.Geometry.Unit.CreateFromJson(unitJsonMi);
scaleBarDef.Units = unitMi;
}
alternatingScaleBar.SetDefinition(scaleBarDef);
}
... View more
09-09-2022
10:02 AM
|
2
|
2
|
672
|
POST
|
I have an alternating scalebar in my layout. In my Addin the user selects features they want to locate on the map and zooms to their selection. As long as the map scale required to display all of the features is not zoomed out beyond 1:4000 feet I want the scalebar units to be displayed in Feet and adjust the map scale to make sense for feet. If the map has to zoom out beyond 1:4000 feet to display all of the features I adjust the scale to the nearest 1/2 mile interval that contains all of the features and want the scalebar units to be displayed in Miles. I want to programmatically change the UnitLabel and Units of the scalebar to either feet or miles depending on the scale of the map. I have figured out hoe to access Scalebar's UnitLabel and Units properties. The UnitLabel is set as a string, but the Units needs to be set as an ArcGIS.Core.Geometry.Unit. When I get the Units from the Scalebar as a ArcGIS.Core.Geometry.Unit variable all of its properties that I want to change are read only. How do I set up an instance of an ArcGIS.Core.Geometry.Unit for feet and for Miles so I can set the Scalebar Units property to match the unit rules I am applying to the map scale my Addin is setting? Here is code I have so far: ScaleBar alternatingScaleBar = lyt.FindElement("Alternating Scale Bar") as ScaleBar;
if (alternatingScaleBar != null)
{
CIMDoubleFillScaleBar dfScaleBar = alternatingScaleBar.GetDefinition() as CIMDoubleFillScaleBar;
dfScaleBar.UnitLabel = "Feet";
// I can get the current unit setting of
// the scalebar with this code, but I can't
// change the unit setting of this variable
// and I don't know how to set up my own
// ArcGIS.Core.Geometry.Unit variable that
// I can use to change the Units property.
var sbUnits = dfScaleBar.Units;
}
... View more
09-08-2022
06:44 PM
|
0
|
3
|
760
|
POST
|
I got my original code to work by changing the ICommand declaration to this: public ICommand CmdRemoveFromList
{
get
{
return new RelayCommand((SelectedAPNs) =>
{
// Remove items only when SelectedItem isn't null
if (SelectedAPN != null)
{
// Iterate selected items in APN List
foreach (var item in SelectedAPNs as IList<object>)
{
// Get item as a string
string _APN = item.ToString();
// Remove the APN from the ListParcels variable
ListParcels.Remove(_APN);
}
//Clear the dialog APN list
APNsList.Clear();
// Iterate the APNs in the ListParcels variable
foreach (string ListParcel in ListParcels)
{
// Add the APNs to the dialog list
APNsList.Add(ListParcel);
}
}
}, () => true);
}
} I used the CommandParameter in the RelayCommand declaration, added the as IList<object> to type cast the CommandParameter as an iterable IList of objects in the foreach loop and added }, () => true); at the end of the RelayCommand to provide a return value for the RelayCommand. I verified it worked regardless of whether or not the SelectedItems were visible within the current scroll position of the Listbox. So this is the final solution for the xaml, which is nearly identical to the standard MVVM declarations of a Listbox and Button used in Pro, except that I have added a CommandParameter before the button Command. <ListBox x:Name="lbxAPNList" HorizontalAlignment="Left" Height="143" Margin="10,93,0,0" VerticalAlignment="Top" Width="136" SelectionMode="Extended" ItemsSource="{Binding APNsList}" SelectedItem="{Binding SelectedAPN}"/>
<Button x:Name="btnRemoveFromList" Content="Remove from List" CommandParameter="{Binding ElementName=lbxAPNList, Path=SelectedItems}" Command="{Binding Path=CmdRemoveFromList}"/> And this is the final code for the ViewModel, which uses the standard MVVM code for the Listbox source and SelecedItem and only makes slight variations in the standard MVVM ICommand declaration for the button. private ObservableCollection<string> _apnsList = new ObservableCollection<string>();
public ObservableCollection<string> APNsList
{
get { return _apnsList; }
set
{
SetProperty(ref _apnsList, value, () => APNsList);
}
}
private string _selectedAPN;
public string SelectedAPN
{
get { return _selectedAPN; }
set
{
SetProperty(ref _selectedAPN, value, () => SelectedAPN);
}
}
// ListParcels is populated by another button and matches the listbox
// It ensures the list is alphabetically sorted and all values are unique
public static SortedSet<string> ListParcels { get; set; }
public ICommand CmdRemoveFromList
{
get
{
return new RelayCommand((SelectedAPNs) =>
{
// Remove items only when SelectedItem isn't null
if (SelectedAPN != null)
{
// Iterate selected items in APN List
foreach (var item in SelectedAPNs as IList<object>)
{
// Get item as a string
string _APN = item.ToString();
// Remove the APN from the ListParcels variable
ListParcels.Remove(_APN);
}
//Clear the dialog APN list
APNsList.Clear();
// Iterate the APNs in the ListParcels variable
foreach (string ListParcel in ListParcels)
{
// Add the APNs to the dialog list
APNsList.Add(ListParcel);
}
}
}, () => true);
}
}
... View more
09-07-2022
05:22 PM
|
0
|
0
|
6178
|
POST
|
I have a ListBox in my ProWindow which is configured for Extended selection so that the user can select multiple items. I also have a button which is supposed to remove the selected items from the list. I set up the binding for the ListBox as an ObservableCollection. If the Selection mode for the Listbox was Single I would set up a binding for the SelectedItem property of the Listbox. However, when the selection mode is set up for Extended selection I want to use the SelectedItems property, not the SelectedItem property. But I am not sure how to set up the binding in my ViewModel so I can get the IList from the SelectedItems property, which is a read only property. (I don't need to set the SelectedItems, I only need to get it) I have read that there is a way to pass the SelectedItems property of the ListBox to a Command using a CommandParameters property. It says that the CommandParameter should be declared before the Command binding. The button xaml code is supposed to look something like this: <ListBox x:Name="lbxAPNList" HorizontalAlignment="Left" Height="143" Margin="10,93,0,0" VerticalAlignment="Top" Width="136" SelectionMode="Extended" ItemsSource="{Binding APNsList}" SelectedItem="{Binding SelectedAPN}"/>
<Button x:Name="btnRemoveFromList" Content="Remove from List" CommandParameter="{Binding ElementName=lbxAPNList, Path=SelectedItems}" Command="{Binding Path=CmdRemoveFromList}"/> However, I am not sure how to set the ViewModel ICommand declaration up so that I can use that command parameter. I tried the following but it doesn't work, since the code is never triggered: private ObservableCollection<string> _apnsList = new ObservableCollection<string>();
public ObservableCollection<string> APNsList
{
get { return _apnsList; }
set
{
SetProperty(ref _apnsList, value, () => APNsList);
}
}
private string _selectedAPN;
public string SelectedAPN
{
get { return _selectedAPN; }
set
{
SetProperty(ref _selectedAPN, value, () => SelectedAPN);
}
}
// ListParcels is populated by another button and matches the listbox
public static SortedSet<string> ListParcels { get; set; }
public ICommand CmdRemoveFromList(IList<object> SelectedItems)
{
get
{
return new RelayCommand(() =>
{
Message = "";
// Iterate selected items in APN List
foreach (var item in SelectedItems)
{
// Get item as a string
string _APN = item.ToString();
// Remove the APN from the ListParcels SortedList
ListParcels.Remove(_APN);
}
//Clear the dialog APN list
APNsList.Clear();
// Iterate the APNs in the module ListParcels variable
foreach (string ListParcel in ListParcels)
{
// Add the APNs to the dialog list
APNsList.Add(ListParcel);
}
});
}
} Is there a way to get the SelectedItems property of a ListBox for use by a button ICommand declaration that works with the Pro SDK?
... View more
09-07-2022
02:25 PM
|
0
|
4
|
6206
|
POST
|
Also, the BindingContext is set up properly in my xaml file since my bindings and code are working property and giving change notifications from my textboxes, buttons and listboxes in response to the get and set code of the properties I set up for them. Only the radiobuttons and checkboxes bindings and notifications are not working. However, you are right that I copy/pasted properties that were set to private and didn't notice it. Changing it to public solved the issue.
... View more
09-06-2022
05:04 PM
|
0
|
0
|
944
|
POST
|
I am having trouble understanding how to implement RadioButons and CheckBoxes using MVVM. It seems that Binding the IsChecked property to a bool get/set ViewModel property doesn't work. What is the trick? Here is my xaml set up for the radio buttons: <StackPanel x:Name="StpMatchType" HorizontalAlignment="Left" Height="65" Margin="19,114,0,0" VerticalAlignment="Top" Width="134">
<RadioButton x:Name="rbStart" GroupName="Test" Content="Start of Name" Height="20" IsChecked="{Binding Path=RBStart,Mode=TwoWay}"/>
<RadioButton x:Name="rbAnyPart" GroupName="Test" Content="Any Part of Name" Height="20" IsChecked="{Binding Path=RBAny,Mode=TwoWay}"/>
<RadioButton x:Name="rbExact" GroupName="Test" Content="Exact Name" Height="20" IsChecked="{Binding Path=RBExact,Mode=TwoWay}"/>
</StackPanel>
<CheckBox x:Name="CbxTitle" Content="Set Map Title" HorizontalAlignment="Left" Margin="19,203,0,0" VerticalAlignment="Top" Height="15" Width="90" IsChecked="{Binding SetTitle}"/>
And here are the ViewModel property set up, but this code is never triggered at set up or when I click on one of the radiobuttons: private bool _rbStart = true;
private bool RBStart
{
get { return _rbStart; }
set
{
_rbStart = value;
NotifyPropertyChanged(() => RBStart);
}
}
private bool _rbAny = false;
private bool RBAny
{
get { return _rbAny; }
set
{
_rbAny = value;
NotifyPropertyChanged(() => RBAny);
}
}
private bool _rbExact = false;
private bool RBExact
{
get { return _rbExact; }
set
{
_rbExact = value;
NotifyPropertyChanged(() => RBExact);
}
}
public bool SetTitle
{
get { return Module1.SetTitle; }
set
{
Module1.SetTitle = value;
NotifyPropertyChanged(() => SetTitle);
}
}
//Module1 Code
private static bool _setTitle;
public static bool SetTitle
{
get { return _setTitle; }
set
{
_setTitle = value;
}
}
It seems like all of the Google examples are overly complex and solving value conversion problems that don't apply to me. Even my code seems like overkill, since the behavior of the set of radiobuttons and checkboxes works fine while it ignores my code. I don't want to modify the default behavior of the radiobuttons or checkboxes at all and I don't really have to be notified or do anything when the user actually changes the radiobutton selection or checkbox state. I just need to be able to access the bool state of these buttons in my ViewModel when I trigger some of my other methods. If I can do that without actually needing to bind any of the radiobuttons or checkboxes, that would be great.
... View more
09-06-2022
04:32 PM
|
0
|
3
|
990
|
POST
|
I have adapted my code to generally follow the the example you provided and was able to get the buttons to close the ProWindow the way I wanted. However, I am not sure I have adapted the code in a way that is fully consistent with keeping the Model separate from the ViewModel. In the example provided the Show button class generated with the ProWindow class seems to have been used as the Model class for the MVVM interactions with the map and/or data. However, I am not using the Show button class created for the ProWindow to launch it. Instead I am using a class that sets up the map with layers that support multiple ProWindow options and launch the appropriate ProWindows based on the choice the user makes in a combobox. That class already has extensive code and I don't want to expand it with the code that the example used in the Show button class. But I am willing to create a new class or call the Show button class to handle the Model portion of the MVVM approach for each ProWindow, if that is recommended. The Cancel button that just closes the ProWindow is fine and fully consistent with the purpose of the ViewModel since it does not interact with the map or any data. The other button, called the Locate button, currently is working the way I want it to work, but it is performing map and data operations in the ViewModel that may be better handled in a separate Model class according to MVVM. I would appreciate comments on which portions of this code should be moved from the ViewModel into a separate Model class to make it more consistent with the approach recommended for MVVM. Here is the code: public ICommand CmdLocate => new RelayCommand(async (proWindow) =>
{
String layerName = "Search PLUS Cases";
var ActMap = MapView.Active;
var fLayer = ActMap.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name.Equals(layerName));
if (fLayer != null)
{
if (PLUSCase != null && PLUSCase != "")
{
string whereClause = "CASE_ID = '" + PLUSCase.Replace("'", "''") + "'";
var iCount = await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
// Set up Definition Query filter for the layer
Module1.SetLayerDefinition(fLayer, whereClause, "PLUS Cases");
// Count the filtered features in the layer
var cnt = 0;
using (var cursor = fLayer.Search())
{
while (cursor.MoveNext())
cnt++;
};
if (cnt > 0)
{
// Pause Drawing
ActMap.DrawingPaused = true;
// Clear all selected features in the map
ActMap.Map.SetSelection(null);
// Select the filtered features
fLayer.Select();
// Zoom to Selection
ActMap.ZoomToSelected();
// Reset the camera zoom to zoom out slightly
MapView mapView = ActMap;
// Get the camera for the Active MapView
Camera camera = mapView.Camera;
// Increase the scale by 40%.
camera.Scale *= 1.4;
// Zoom to the camera scale
mapView.ZoomToAsync(camera, TimeSpan.Zero);
//Make the layer visible
fLayer.SetVisibility(true);
// Resure Drawing
ActMap.DrawingPaused = false;
}
else
{
//Make the layer invisible
fLayer.SetVisibility(false);
}
return cnt;
});
// If no selected features
if (iCount == 0)
{
// Show message that No Case Match was found
Message = "No Match Found!";
}
else
// If there are selected features
{
// TODO: set dialog result and close the window
(proWindow as ProWindow).DialogResult = true;
(proWindow as ProWindow).Close();
}
}
}
}, () => true);
... View more
09-06-2022
08:49 AM
|
0
|
0
|
635
|
BLOG
|
The code works in Python 2.7 32 bit, which ArcMap uses, and in Python 3.X 64 bit which ArcGIS Pro uses. The ArcGIS Pro Python requires that you maintain an active connection to ArcGIS Online through ArcGIS Pro to work, so whether or not you normally use ArcGIS Pro you have to periodically open it to maintain the AGOL connection for Python. The Python version you use makes no difference in how you code the dictionary Data Transfer portion of the script. You do have to enclose in parenthesis the outputs of all the print statements in Python 3.X to avoid an error. The advantage of using Python 3.X for this code is that it supports access to more than 2 GB of RAM and is much less likely to fail due to an out of memory error when you work with very large datasets.
... View more
09-03-2022
01:59 PM
|
0
|
0
|
699
|
POST
|
I have a ProWindow dialog that has two buttons. One Button needs to just close the ProWindow and the other button needs to attempt to do an action and if it is successful it needs to close the ProWindow. I would use this.Close() if my buttons were implemented directly in the xaml class of the ProWindow, but I want to use MVVM and want to bind these buttons to the ViewModel and ICommand and RelayCommand. How do I set up the binding so that the button code within the ViewModel class will be able to close the ProWindow?.
... View more
09-01-2022
06:14 PM
|
0
|
2
|
710
|
POST
|
I am using ArcGIS Pro 2.9.3 and have applied a rule package to a building footprint layer with almost 1 million footprint features using a modified version of the Standard Building cga in the Complete Streets example. I am trying to improve refresh performance and am looking for suggestions. I am not satisfied with the options I have tried so far. Prior versions of Pro gave Excessive Refresh Requests errors if I moved the camera in the scene before waiting for each refresh to complete using this layer. Fortunately Pro 2.9.3 seems to have fixed this behavior which at least allows the layer to complete the final refresh when I get the camera where I want it, but refresh performance is still slower than I like once I get to that point. The only suggestion I have seen in the Pro help is to limit the layer scale that will draw in the scene. I have limited the layer scale to 2 miles, which is probably the ideal scale limit for my needs. It works better than having no scale restriction, but it still takes a long time (3 to 5 minutes) for the rule to refresh whenever I pan to an area that forces the cache to reset. Even if I change the scale restriction to a significantly smaller value the refresh performance does not improve very much, and the level of improvement is not worth the limitation of what can be viewed in the scene. It seems that most of the refresh time is still being used to evaluate the vast set of features that ultimately are not displayed. I have 3D Analyst and considered converting the buildings into multipatch features, which does improve performance. If I exclude textures and colors when I build multipatches for the buildings the fgdb file is almost 2 GB, which is a reasonable size. However, I want the rule textures in the final symbology and I don't know of any way to apply the rule textures after generating multipatches it I didn't include the textures through the conversion tool. Unfortunately, if I include textures and colors when I generate multipatches the output file would be between 300 to 400 GB (I cancelled the tool when the file grew to 55 GB after about 15% of progress). That is too large to be justified. I haven't tried this option, but applying a definition query on the layer to limit the extent displayed by the layer using fields with an attribute index, like fields containing centroid coordinate values or community names, should improve performance. However, most of my users wouldn't know how to adjust the definition query when they moved beyond the initial query limits. I could setup separate scenes in advance that limit the amount the user can move, but I don't think my users would know which scene they needed to open to view a particular area given the large number of communities my jurisdiction covers. Setting up tiled layers could be done and placed in a scene, but I would think that performance would only be improved if the layers knew how to turn their visibility on or off in response to the camera position. It is unlikely my users could manually manage to adjust the layer visibility settings any better than they could manage separate pre-made scene files. I don't think there would be any improvement over using the original feature class if the user eventually ends up setting all of the tiled layers to being visible all the time. Is there something I am overlooking? I know how to program and am learning the Pro SDK, so a custom solution is possible. But I was hoping that applying some out of the box techniques would make going that route unnecessary.
... View more
08-04-2022
06:39 PM
|
0
|
0
|
297
|
IDEA
|
I voted for your idea and would have a use for this. Please also vote for my idea, which gives other examples of how it would be useful to be able to use Arcade for some of the parameters of other tools. Allow Arcade Expressions in Parameters of Geoprocessing Tools
... View more
07-27-2022
04:33 AM
|
0
|
0
|
1951
|
IDEA
|
One of the improvements introduced in ArcGIS Pro is the ability to use Arcade expressions not only as a replacement language where ArcMap used languages like Python or VB Script, such as Labels and Display Expressions, but in new places where ArcMap does not support custom expressions as inputs, such as the Symbology tab. In ArcMap, the Symbology tab only takes existing fields as valid inputs for the unique value category symbology options or the quantities symbology options, which does not allow the user to apply reclassified values or unit conversions to the values in a field without calculating over the values or adding and calculating a new field. However, in ArcGIS Pro the user can use an Arcade Expression instead of a field that can eliminate the need to create or calculate any field in the source data to accomplish symbology effects that present the data under classifications or in units of measure that are not directly stored in the source attributes. However, while applying an Arcade expression to the Symbology tab gives the appearance that the features have merged and dissolved together based on the user defined custom field values, the underlying features have not actually dissolved according to that Arcade expression and cannot be used in a geoprocessing workflow that needs an actual Dissolved feature class that is based on the case values the user custom defined using Arcade. To create the actual Dissolve feature class in ArcGIS Pro the user still needs to add a new field to the source data and calculate the values to be stored in the table prior to running the Dissolve tool. This becomes a real problem when the user has to make a copy of the source data in order to make changes to the schema and the source features class is very large and is only updated on a relatively small percentage of its features each day. The geoprocessing steps required simply to copy the source data, add the field and calculate its values are extremely time consuming and can take up the bulk of the time required to rerun many geoprocessing models if the user is trying to maintain outputs that approach anything resembling real time concurrency with the underlying large data sources. However, if I was able to use an Arcade Expression for the Summary fields or Case field in the geoprocessing tools that do aggregation, like the Dissolve tool, Summary Statistics tool, Frequency tool or Spatial Join tool, I could accomplish the same thing that an Arcade expression now can accomplish in the Symbology tab, but actually output a feature class rather than just the artificial appearance of that dissolve in a map that is only accessible in my project and not suited for further geoprocessing analysis. If Arcade was incorporated into those tools to extend the options available in the parameters that currently only accept fields as inputs, I would be able to eliminate all of the geoprocessing steps currently required to copy the source data and add fields calculated with custom field values to achieve the desired reclassified geoprocessing output. Although not all geoprocessing tool parameters may be suitable to be extended to allow Arcade expressions as alternatives to the standard validated parameter types and the introduction of Arcade into geoprocessing tools presents new challenges for validating the tool parameters, the value of the time saved by users would more than justify the effort in many cases, like the aggregation tools I mentioned. I am sure that many temporary files currently required to carry out most geoprocessing workflows could be eliminated if Arcade was introduced as an option for at least some of the existing geoprocessing tool parameters. Additionally, incorporating Arcade expressions as an option directly implemented for at least some of the geoprocessing parameters would make Arcade even more more portable and reusable across the platform and support the creation of a much larger array of outputs that not only can be used within ArcGIS Pro application itself, but can be used to create outputs that could be exported in formats that are suitable for external use in such things as Traffic Models.
... View more
07-15-2022
09:58 AM
|
6
|
2
|
1024
|
Title | Kudos | Posted |
---|---|---|
1 | 05-07-2014 03:27 PM | |
1 | 08-03-2024 09:18 AM | |
3 | 08-08-2024 11:46 AM | |
3 | 07-18-2024 02:58 AM | |
1 | 07-08-2024 09:51 AM |
Online Status |
Offline
|
Date Last Visited |
Sunday
|