More

Saving Feature Class Symbology into Layer or Object to apply to another Feature Class?

Saving Feature Class Symbology into Layer or Object to apply to another Feature Class?


I am creating a tool to automate a data standardization process. Part of this process is saving the feature class (variable "filename") as a layer file, projecting it into another coordinate system (variable "wmsde"), and then saving that one as a copy as well. I want the user to symbolize the feature class and then run the script/tool which would take the symbology they designated and apply it to the layers created. I realize it is incredibly easy to right click the layer and click Save As Layer, but I want as much as possible of this process to be automated. I am trying to use representations but a layer with the symbology needs to exist before the tool is used, which would be fine if I could find a way to save the symbology to a layer file. I have tried arcpy's Make Feature Layer and Save to Layer File (Management) to create a layer from the data but it does not save the symbology. I read on an answer to another question on here that this may be normal. I think the representation tool is working because the second layer's symbology is the same color as the first's (and they are usually assigned random colors). However the Drop Representation tool is failing and I'm not sure why. I get error 000252. Here is the (edited) code I have for it. Other tools that create symbology for a layer such as Apply Symbology From Layer (Data Management) also requires a symbolized layer.

Does anybody have any ideas as to what I can do to save the user's symbology designations or even another route aside from representations?

arcpy.env.workspace = r'C:DataData.gdb' worksde = r"C:UsersmeAppDataRoamingESRIDesktop10.2ArcCatalogDatabaseName.sde" lyrFolder = r"C:Layers" ws = arcpy.env.workspace filename = r"PlayAndTest" sdefilename = r"PlayAndTest" infile = os.path.join(ws, filename) sdefile = os.path.join(worksde, sdefilename) # Create a DD layer file print "Creating DD LYR" DDlyr = os.path.join(lyrFolder, filename + "_DD.lyr") arcpy.SaveToLayerFile_management(filename, DDlyr) # Reproject as WM print "Projecting to WM" wmsde = sdefile + "_WM" prjfile = os.path.join(arcpy.GetInstallInfo()["InstallDir"], "Coordinate SystemsProjected Coordinate SystemsWorldWGS 1984 Web Mercator (auxiliary sphere).prj") spatialRef = arcpy.SpatialReference(prjfile) arcpy.Project_management(infile, wmsde, spatialRef) # Make the WM Layer WMlyr = os.path.join(lyrFolder, sdefilename + "_WM.lyr") arcpy.SaveToLayerFile_management(sdefilename, WMlyr) arcpy.ApplySymbologyFromLayer_management(WMlyr,DDlyr)

First, feature classes don't have symbology attributes. Symbology is attributed to layers in ArcGIS. When you add a feature class to a table of contents in ArcMap, a layer is created, though not saved anywhere as a .lyr file.

If you are having your users add a feature class to ArcMap that they then symbolize as desired, below is the way of saving that symbolization to a layer file (.lyr). The variable infile is a string of the layer name as it appears in ArcMap's table of contents.

# Create a DD layer file print "Creating DD LYR" DDlyr = os.path.join(lyrFolder, filename + "_DD.lyr") arcpy.SaveToLayerFile_management(infile, DDlyr)

Also note that if you don't want to save an actual file, you can useDDlyr = arcpy.mapping.Layer (infile). Then the variable DDlyr will store a layer object with symbology.

This is all redundant however, since, as mentioned, ArcMap creates a layer whenever a feature class is added to a table of contents. Because this is the case, you can simply use the layer name as it appears in the table of contents to tell arcpy which layer to use as your input. Thus, assuming once again that the variableinfileis a string of the layer's name as it appears in the table of contents, you can bypass creating another layer object and simply use the following as your AddRepresentation code:

arcpy.AddRepresentation_cartography(wmsde, represent, "RuleID","Override", "STORE_CHANGE_AS_OVERRIDE", infile, "Assign")

I hope this helps!


Version 1.8.3 of the ArcGIS API for Python is here

The Python API is designed to serve a wide spectrum of users – from GIS administrators, to Python developers and data scientists. Our users have trusted the API and use it to administer their web GIS, publish, update and clone a wide variety of GIS data, build sophisticated analytical models and automate their mission critical workflows. Over the last few years, the API has grown from a quaint little library to one with several different modules. Now we have over 2300 methods and functions!

Article Summary: v1.8.3 of the ArcGIS API for Python has been released. This release adds a slew of new features and capabilities.

  • No time to read the full article? Scroll to the end for an 1 slide overview.
  • Want the complete list of new features? You can get them from the release notes.
  • Ready to try out the new API? You can upgrade by typing conda upgrade -c esri arcgis into your anaconda prompt.

The picture above (presented at Python Libraries for Spatial Data Science talk) distills some of the key capabilities of the API. At version 1.8.3, we have tried to enhance each of these aspects and this blog is a rundown of the top features.


base graphics draw directly on a device.

2- the recently introduced gridGraphics package, to convert base graphics to their grid equivalent

I am very late to this, but it was the first question which showed up when I searched for the question. So I'd like to add my solution for future viewers who come across the question.

I solved this by using a function instead of an object. For example, suppose we want to compare two beta distributions with different parameters. We can run:

And save the plots as functions rather than objects.

Next, we can call each plot as we want by simply calling the two plots as functions rather than objects.

Hope that helps someone who stumbles across this later!

You can use the active binding feature of the pryr package if you don't want to directly change the values of the object created.

Each time you type a on the console the graph will be reprinted on the screen. The %<a-% operator will rerun the script every time (in case of one graph this is not a problem I think). So essentially every time you use a the code will be rerun resulting in your graph which of course you can manipulate (overlay another plot on top) or save using png for example. No value itself will be stored in a however. The value will still be NULL.

I don't know if the above is what you are looking for but it might be an acceptable solution.


Adding an Existing Annotation Layer

My program's purpose is to go through every .mxd file in a given directory, delete their old and broken annotation layers, and add in new ones for specific feature classes. The old annotation sources in the geodatabase are combined into a single annotation file per feature class type. (So instead of having bAnno1, bAnno2. it would be bAnnos. This saves space and lessens ArcGIS editing time.)

My problem is the creation of the new annotation layers. My original code was along these lines (creating the first five variables only once outside loops):

The added layers match the original annotation layers in everything but the Symbology. In other words, ArcGIS sees these added files as a Feature Class of polygons instead of an Annotation Class with words. Looking at my code, I can see why.

So how do I make it exclusively an annotation layer? Or how do I make an annotation layer using an existing source in a dataset in the geodatabase?

Failed attempts include using:

One of the above methods might actually be the answer I could be incorrectly doing things.

Additional details: using ArcGIS 10, working with .mxd files made from ArcGIS 9.3 and 10.


5 Answers 5

Instead of using Grid Search for hyperparameter selection, you can use the 'hyperopt' library.

Please have a look at section 2.2 of this page. In the above case, you can use an hp.choice expression to select among the various pipelines and then define the parameter expressions for each one separately.

In your objective function, you need to have a check depending on the pipeline chosen and return the CV score for the selected pipeline and parameters (possibly via cross_cal_score).

The trials object at the end of the execution, will indicate the best pipeline and parameters overall.

Although the solution from dubek is more straight forward, it does not help with interactions between parameters of pipeline elements that come before the classfier. Therefore, I have written a helper class to deal with it, and can be included in the default Pipeline setting of scikit. A minimal example:

It can also be used for other elements of the pipeline, not just the classifier. Code is on github if anyone wants to check it out.

Edit: I have published this on PyPI if anyone is interested, just install ti using pip install pipelinehelper .

Another Simple solution to the problem.

First load all the estimators. Here I will be using classifiers mostly.

After that create a list of classifiers:

Now, Create all parameters for each classifier/estimator:-

Now create a list of them:

Now, comes the most important part: Create a string names for all the models/classifiers or estimators: This is used to create the Dataframes for comparison


1 Answer 1

There are a few approaches to this.

Old school classname toggling

Pass a prop down to the child component that reflects the state. On the child, use that prop to conditionally render one or more classes that represent the desired presentation.

Assign styles via style prop

This is similar to #1, but eliminates a layer of abstraction. Instead of assembling a class list you just assemble the CSS styles you'd like to apply as an object.

Use a CSS-in-JS library

The downside of the above approach is that you wind up duplicating styles for each instance of your element on the page. CSS-in-JS libraries solve this by extracting your styles into an automatically generated class and applying the class to your component instead. I prefer Emotion, but there are others.

Using Emotion you're able to accept a className prop from the parent that override the defaults set by the child. This inversion-of-control is really powerful and solves many of the shortcomings with early CSS-in-JS approaches.

In the above example, className is assigned by Emotion using the generated class name assigned based on the css prop passed to ChildComponent inside of ParentComponent . The result of this would be a div with a blue border and blue text when someState is false (default). When someState is switched to true , the border and text will be red. This is because the styles passed in via className will override the styles assigned directly via css in Emotion.


Exploring Data in the Map View

Selecting Features Manually from the Map View

  1. On the Map tab, in the Selection group, click the Select button.

The selected neighborhood will be outlined in cyan.

  1. Drag a box to select multiple adjacent neighborhoods.
  2. Hold downShift and clickany non-selected neighborhood to add additional non-adjacent neighborhoods to the selection.
  3. Hold downCtrl and clickany selected neighborhood to deselect neighborhoods.

When you are finished using a selection, it is important to clear the selected features, because the majority of tools in ArcGIS Pro only run on selected features. Therefore, if you run a tool anticipating that you will be processing all features in a particular layer and you inadvertently left some features selected from a previous process, only those selected features will be processed, which will lead to unexpected results.

    On the the Map tab, in the Selection group, click the Clear button to clear the selected features.

Notice that the Clear button becomes grayed out once all features are cleared. On the Map tab, notice that the Select button is still activated, which means that if you now attempted to pan the map by clicking and dragging your left mouse button across the map, you would, instead, select numerous features on your map inadvertently. To prevent this, it is a good idea to reactivate the Explore button as soon as you are finished using manual selection.

Selecting Features Manually from the Table View

  1. In the Contents pane, right-click the Census_2010_By_SuperNeighborhood layer name and selectAttribute Table.

A table view now appears docked beneath your map view. Each row, or record, in your table corresponds to exactly one super neighborhood polygon on the map. Each column, or field, in your table represents a variable describing the super neighborhoods.

Every geodatabase feature class has two to four default fields, which cannot be edited or deleted. The leftmost OBJECTID field is a unique ID that is automatically numbered from 1 to the total number of features at the time of creation. In this particular case, the field is called OBJECTID_1, because there was a preexisting OBJECTID field at the time this data was imported to geodatabase format by the City of Houston. The Shape field indicates whether the feature geometry contains points, lines, or polygons.

  1. In the table view, use the scroll bar at the bottom to scroll to the far right of the table.

The other two default fields are the last Shape_Length and Shape_Area fields which contain the perimeter and area of the super neighborhoods, respectively. A line feature class will only contain the Shape_Length field and a point feature class will not contain either field. The units of these fields correspond to the units of the projection in which the data coordinates are stored.

  1. In the Contents pane on the left, double-click the Census_2010_By_SuperNeighborhood layer name.
  2. In the 'Layer Properties' window, in the left column, click the third tab, Source.
  3. At the bottom of the window, click to expand the Spatial Reference section.
  4. Use the scroll bar on the right to scroll to the bottom of the Spatial Reference section to view the metadata.

Within the Spatial Reference section, notice that the geographic coordinate system is WGS 1984 and that no projected coordinate system is listed. Therefore, the layer is unprojected, meaning the data coordinates are located on the three-dimensional surface of the globe and you can see the Angular Unit is listed as Degrees (or decimal degrees.) Therefore, the Shape_Length field is displaying decimal degrees and the Shape_Area field is displaying square decimal degrees, which is why the numbers are so low. Before measuring distance or area, the data layer should be projected onto a two-dimensional surface. The resulting projection will have a Linear Unit, such as feet or meters. The process of p rojecting is further covered in the Introduction to Coordinate Systems and Projections course.

As indicated by the layer name, the majority of the remaining fields contain 2010 census data that was aggregated to the super neighborhood level by the City of Houston, since that is not a geographic unit at which the Census Bureau provides data.

  1. Double-click the 'Name' field header to sort the neighborhoods alphabetically.
  2. To select a neighborhood from the table, click the gray square to the far left of each row.
  3. To select an adjacent section of records, hold downShift and select a record below or above the currently selected record to automatically select all records in between.
  4. To add or remove individual records from the selection, hold downCtrl and select another record.

Notice in the bottom left corner of the Census_2010_By_SuperNeighborhood attribute table, it indicates the number out of 88 table records (and corresponding map features) that are currently selected.

The two buttons to the left allow you to toggle between 'Show all records' and 'Show selected records'.

Note that if 'Show selected records' is active and no records are currently selected, the table view will appear empty. Toggle back to 'Show all records' to view the table.

    At the top of the Census_2010_By_SuperNeighbrhood table view, click the Clear button.


5 Answers 5

It looks like the [BsonIgnore] attribute did the job.

Alternatively, if you don't want to use the attribute for some reason (e. g. in case you don't want to bring an extra dependency to MongoDB.Bson to your DTO), you can do the following:

Also you can make IsOwner Nullable and add [BsonIgnoreExtraElements] to the whole class:

A property with null value will be ignored during serialization. But I think [BsonIgnore] will be better for your case.

Just in case somebody might be interested in another way of doing it. Via conventions:

And then you need to register this convention once during you app startup:

You should probably want to combine the two attributes BsonIgnoreExtraElements and BsonIgnore. The reason for that is although BsonIgnore will not insert the "IsOwner" property to you DB but if you have "old" instances in your DB that contained this field and you will remove this fields from your model in the feature or extend your "GroceryList" class and use your new class in the DB will get an exception:

"Element 'IsOwner' does not match any field or property of class."

Another way (instead of editing you model class) is to use "Register Class Map" with "SetIgnoreExtraElements" and "UnmapMember" together.


11 Answers 11

If you only use a small subset of the third party API, it makes sense to write a wrapper - this helps with encapsulation and information hiding, ensuring you don't expose a possibly huge API to your own code. It can also help with making sure that any functionality you don't want to use is "hidden".

Another good reason for a wrapper is if you expect to change the third party library. If this is a piece of infrastructure you know you will not change, do not write a wrapper for it.

By wrapping a third party library you add an additional layer of abstraction on top of it. This has a few advantages:

Your code base becomes more flexible to changes

If you ever need to replace the library with another one you only need to change your implementation in your wrapper - in one place. You can change the implementation of the wrapper and don't have to change a thing about anything else, in other words you have a loosely coupled system. Otherwise you would have to go through your whole codebase and make modifications everywhere - which is obviously not what you want.

You can define the API of the wrapper independently of the API of the library

Different libraries can have vastly different APIs and at the same time none of them may be exactly what you need. What if some library needs a token to be passed along with every call? You can pass the token around in your app wherever you need to use the library or you can safe it somewhere more centrally, but in any case you need the token. Your wrapper class makes this whole thing simple again - because you can just keep the token inside your wrapper class, never exposing it to any component inside your app and completely abstract away the need for it. A huge advantage if you ever used a library which does not emphasise good API design.

Unit testing is way simpler

Unit tests should only test one thing. If you want to unit test a class you have to mock its dependencies. This becomes even more important if that class makes network calls or accesses some other resource outside of your software. By wrapping the third party library it is easy to mock those calls and return test data or whatever that unit test requires. If you don't have such a layer of abstraction it becomes much more difficult to do this - and most of the time this results in a lot of ugly code.

You create a loosely coupled system

Changes to your wrapper have no effect on other parts of your software - at least as long as you don't change the behaviour of your wrapper. By introducing a layer of abstraction like this wrapper you can simplify calls to the library and and almost completely remove the dependency of your app on that library. Your software will just use the wrapper and it won't make a difference how the wrapper is implemented or how it does what it does.


4 Answers 4

When you are in Camera RAW, make whatever adjustments you like, then press the shift key. The open button changes to Open Object. This gives you a re-editable object -- i.e., you can dive back into Camera RAW if you like simply by double-clicking the smart object layer.

All of that said, if you make any raster level adjustments in Photoshop -- say a spotting / healing layer, then go back into Camera RAW to tweak the color balance, all your dust busting will be the wrong color. There are techniques for working with Smart Objects, but at the end of most post-processing, you have to commit to some pixel-level stuff otherwise you wouldn't have broken out a big hammer like Photoshop in the first place, right?

Do you have a use-case for this extra level of flexibility? That would help with a more complete answer that addresses specific concerns.

In Photoshop CC, go to the top menu bar, select the word 'filter'. In the drop down menu select 'camera raw filter'.

Your current layer will then be opened with the camera raw editing window.

OR The keyboard shortcut is: shift + ⌘ command + A (select them all at the same time).

I'm not sure that what you want is exactly possible, because Photoshop doesn't edit the file as a RAW file but rasterizes it and then allows you to edit it.

You can try the following technique and it should work almost the way you want.

In Camera Raw, you will see at the bottom it shows the image's profile in blue text.

Something like
Adobe RGB (1998) 8 Bit 5184 by 3456 (17.9MP) 240 ppi

Click on that and you'll find a check box for "Open in Photoshop as Smart Objects". After selecting that and clicking OK, you'll notice the Open Image button has become Open Object. If you Open Object you'll see that it's now a Smart Object in Photoshop and if you double click the layer, it opens the image in Camera Raw.

With the image as a Smart Object, you probably won't be able to do all the edits you're normally able to do such as Burning/Dodging but using Fill/Adjustment layers, which is a good idea anyway, you will still be able to do Color Balance and Exposure type edits.


Watch the video: Getting back to GIS basics Features, Feature Classes, and Layers