|
POST
|
I meant to say Illustrator, not Photoshop. Sorry about the confusion. My other Graphics program also created vector shapes and outputted to wmf, which I had to convert to emf. So all my emf files are vector files and have never been created as or converted to raster. Everything has been done as Shape Markers, not Picture Markers and the import from ArcMap was to Shape Markers. So it does not come down to raster vs. vector, since the emf files have never been raster. I am not at home to test the Paths panel, so that will have to wait. I know the files show up when I use the Shape Marker browse function.
... View more
07-19-2016
08:30 AM
|
0
|
0
|
5497
|
|
POST
|
I believe the maximum number of digits stored internally in a double is 17 digits, so you may have exceeded the limits of what it is capable of displaying reliably. At least this is true in .Net. System.Double "Because some numbers cannot be represented exactly as fractional binary values, floating-point numbers can only approximate real numbers. All floating-point numbers also have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number. A Double value has up to 15 decimal digits of precision, although a maximum of 17 digits is maintained internally. "
... View more
07-18-2016
01:38 PM
|
1
|
1
|
4072
|
|
POST
|
A huge reason to use a geodatabase is that Attribute Assistant does not work with shapefiles. Attribute Assistant should be part of every editing experience, especially if you run a lot of calculations and things like attribute and spatial joins as part of your data maintenance routines. Those can be eliminated for the most part.
... View more
07-16-2016
12:32 PM
|
1
|
0
|
4182
|
|
POST
|
If that is true then there is no point to an emf file option, since they would never work as no one would create one for a symbol that is already available from the standard gallery. Also that does not explain how my symbols came across when I import the layer from ArcMap, since none of my emf symbols are in the gallery of either program. They are house footprints and both the rectangular ones that may be close to a gallery symbol (but use different height to width ratios than any gallery symbol) and irregular ones can be imported but not used directly in Pro.
... View more
07-16-2016
01:45 AM
|
0
|
1
|
5497
|
|
POST
|
I have one item you mentioned in favor of shapefiles where me experiences show geodatabases to be equal to or better than shapefiles. File geodatabases are always the fastest for geoprocessing and cursor access in my experience over shapefiles and that is one reason I never use shapefiles for geoprocessing. Edit: I reread your last point more carefully and realized my experience did not contradict your point about single user editing.
... View more
07-15-2016
06:15 PM
|
1
|
2
|
4372
|
|
POST
|
I have attached a zip of the emf files I am testing. It has been a long time since I created them and I have used many different methods over the years, so I can't exactly say how they were created other than the fact that at that time I originally created them as wmf files and used a freeware converter to make them into emf files. At work I export straight to emf from photoshop, but at home I don't have photoshop and my graphics program only generates wmf files which I have to convert. Emf files produced by both methods have always worked in ArcMap Desktop. Also thanks for the help page explaining Rotation. I was looking at the properties of the symbol itself, which only shows the Rotate Clockwise and Angle options under the Rotation heading. The unified interface can be a little confusing when it uses identical headings in the menus to mean different things depending on the context. In my view it would be nice to have a link in the symbol properties menu to link me to the connected properties menu and vice versa when the two properties apply to the same item (a layer) and have the same heading (Rotation), and affect the same thing (the display of the symbol on the map) but appear under different context menus (symbol shape and connected attributes). Although I am new to ArcGIS Pro, I am not a novice user of ArcGIS, so I understand where these two setting relate back to the Desktop symbology tabs, but it is still confusing. I guess I will have to get used to that, since I seem to recall that at one time the layer symbology menus in desktop were similarly confusing. But at this point I consider this increased separation of two related, nearly identical, properties of the layer to be even less obvious to navigate than Desktop was.
... View more
07-15-2016
04:24 PM
|
0
|
3
|
5497
|
|
POST
|
The tool behaved normally. All of the parcels not selected that have red on them took the FZONE_CODE value from the FIRST feature encountered and ignored all other values (in the cases not selected the COM value was not on the first feature encountered and was ignored). You either need to use the One to Many option as Dan mentioned or the One to One option using the JOIN field merge rule on the FZONE_CODE, increasing length for the Zone field and setting a delimiter. For the later the line would change to (changes in bold): + """FZONE_CODE "FZONE_CODE" true false false 60 Text 0 0 ,Join,#,", ""+ FZon3 + """,ZONE_CODE,-1,-1;"""\ The difference is that the One to Many option will create two or more copies of the entire parcel (completely overlapping each other) to match each zoning polygon intersected, and the other will create a single copy of each parcel with a list of multiple zones in the FZONE_CODE field (i.e., "COM, IND"). If you used the field Join merge rule option you would have to select all parcels with "COM" zoning using a LIKE expression with wildcards, not an equals expression (i.e., FZONE_CODE LIKE '%COM%' for a FGDB). Either way, something will be multiplied to capture all parcel and zoning combinations when more than one parcel and one zone intersect. If you want your parcels cut up into separate portions for each zoning polygon that do not overlap and that have an individual code in the FZONE_CODE field then you need to use the INTERSECT tool. However, the INTERSECT tool option requires your topology in both the parcel and zoning feature class to be very clean (no overlaps or gaps) and have very clean edge matches to avoid generating huge numbers of sliver polygons. Spatial Join can overcome bad topology by using a negative tolerance on the features to avoid or at least reduce the effects of slivers at the polygon edges. A negative tolerance also is needed to avoid taking on attributes of polygons that only share an edge if you use the Spatial Join method, since otherwise shared edges are considered an intersecting feature.
... View more
07-15-2016
03:54 PM
|
1
|
0
|
3306
|
|
POST
|
I am unable to get ArcGIS Pro 1.3 to use an *.emf file as a Shape Marker for a point layer. When I press the File button under the Shape Marker symbol option It lets me navigate to a directory with *.emf files and pick one, but when the browse window closes the displayed example symbol does not change and the Apply/Cancel buttons do not activate. All of the other options (basic shape, style and font) work. In ArcGIS Desktop 10.4 I am able to use these *.emf files as point symbols using the Picture Marker Symbol option. If I import an .mxd from ArcGIS Desktop that has a layer containing *.emf point marker symbols into a new ArcGIS Pro project the markers are shown correctly, but I am unable to create that layer within ArcGIS Pro itself even though the ArcGIS Pro help says that *.emf file Shape Markers are supported.. Has anyone been able to set up a layer that uses *.emf marker symbols in ArcGIS Pro? What behavior do you get when you select an *.emf file as a Shape Marker symbol in ArcGIS Pro? Also it appears that point symbols can only use a fixed Rotation angle for all points in the layer and cannot use a Rotation field to set the rotation of each feature uniquely. Is that correct? Is the only work around to create multiple layers that have a definition query for small angle ranges (say 5 degrees) that together cover a full circle and use the midpoint angle of each range as an average rotation for those layers.
... View more
07-15-2016
11:28 AM
|
1
|
11
|
9532
|
|
IDEA
|
It is much less intuitive than Desktop, so since Pro is constantly being touted as a ground up redesign with a focus on fixing Desktop's non-intuitive property access screens, this is one instance where Pro is creating a much less intuitive interface for the field rearrangement aspect at least. In Desktop rearranging the fields in the table view is accessing the field arrangement properties of the field screen, which is the most intuitive in my view. The disconnect is not intuitive, especially when it lets me rearrange fields in the table view but never pointed me to the Fields property screen to make the field arrangement permanent in the Project or warned me that my field reordering would disappear. Now that I know, I regard that feature in the table view screen as nothing but a confusing waste of time and a great way to make sure users of Desktop won't understand how to transition to Pro. I doubt I ever would have figured this out on my own without coming to the forum. Here is a screen shot of what comes up in the help when I launched it from ArcGIS Pro and searched for "field order arcgis pro" Nothing about any Fields property screen is mentioned in any of the topics returned within the first 3 screens of results. I don't know if it is any of the screens, but I would have given up after the 4th screen when topics like "Web scene layer - ArcGIS Pro | ArcGIS for Desktop" came up as a leading topic. .
... View more
07-08-2016
09:35 AM
|
0
|
0
|
2339
|
|
IDEA
|
I know that rearranging a layer in Desktop or ArcGIS Pro does nothing to change the field order in the underlying database, but it does work in Desktop in a saved map, And in Desktop there is a layer property screen that lets me rearrange the fields as well as being able to rearrange the fields in the table view. So even though I realize that this functionality has nothing to do with the underlying database and does nothing to satisfy this idea, it is nonetheless useful to be able to control field order at the layer and map level in Desktop. Anyway, I tried to reorder fields in ArcGIS Pro 1.2 similar to what I can currently do in Desktop. ArcGIS Pro does allow me to reorder the fields in a table view and the fields remain in that order as long as the table view is open. However, if I close the table view and reopen it all of my field reordering disappears. As far as I can see, the ArcGIS Pro properties for the layers do not appear to have any field order screen like the one in Desktop, so there does not appear to be a way to save the field arrangement at the layer level and by extension at the Project level in ArcGIS Pro. Although this probably needs to be under a separate idea, in my view ArcGIS Pro offers no support for any stable field reordering capabilities that would make it useful as even an equivalent of Desktop's current functionality. ArcGIS Pro needs to at least offer a way to save the field rearrangements it lets you do within a Project at the layer level so that it is stable when the table view closes and across different ArcGIS Pro sessions, like Desktop supports.
... View more
07-08-2016
08:33 AM
|
0
|
1
|
3219
|
|
POST
|
I think the way you have written the last part does not accumulated the values from the first key of the dictionary to the last. It only seems to add the current and prior year, not the current and all prior years. I think the last part needs a variable outside the loop to accumulate the summary values for each successive sorted year as shown below: #Print some output
cum = 0
for yearValue in sorted(summaryDict):
cum += summaryDict[yearValue]
print '{0} = {1} acres'.format(str(yearValue), str(cum)) This has the benefit of not needing to assume that each year key has a prior year value, which allows years to be skipped if the data did not have every year (and the first year should throw an error with Joshua's code as shown since there is no prior year key in the dictionary for the first year, but it still needs to print).
... View more
07-05-2016
03:06 PM
|
0
|
1
|
1108
|
|
POST
|
I can confirm that rounding to 3 decimal places or less occurs in several functions of Attribute Assistant. It happens when I convert a number to a string in an expression. The original numeric field has at least 8 significant digits, but the string conversion always rounds it to 2 decimal places, making the string worthless. It appears that either a rounding function is in the background of several methods or a conversion to a fixed floating value with 3 or fewer decimal places occurs, which makes most data stored in double fields worthless. I believe that any expression, including one that just attempts to copy the contents of one double field to another double field will truncate the number of significant digits to 3 or less decimal places. This makes many calculations impossible to perform within Attribute Assistant and I have to use a follow up script or manual process to complete those calculations on data that was originally created by Attribute Assistant. If it preserved the entire number and let me explicitly apply rounding only when I need it I would be able to eliminate those steps.
... View more
07-05-2016
02:15 PM
|
1
|
0
|
4370
|
|
BLOG
|
I have added a section to my blog to include a demo video showing building permit activity by fiscal year. Fiscal Year Field Demo - YouTube. This time based animation demo could not have been done using the original date field of the permits, and only became possible after I used my dateFieldPart Python Field Calculation to create a new Fiscal_Year field derived from the Applied_Date field of the permits.
... View more
07-03-2016
11:08 PM
|
0
|
0
|
1644
|
|
BLOG
|
Dan: Congratulations on being recognized by Jack Dangermond as one of this year's top 3 MVP's on Geonet during the Closing Session of the 2016 UC.
... View more
07-01-2016
08:55 PM
|
4
|
0
|
1644
|
|
BLOG
|
1. There is a lack of ArcGIS/Python resources that support the manipulation of Date Field values using the Field Calculator The ArcGIS software provides good built-in support and documentation that let users take full advantage of the data that they have stored in Text fields or Numeric fields (Short, Long, Float, and Double). This includes built-in support in the Field Calculator that provides quick access to Python methods that let users parse, manipulate and transform the values of an existing field into another field that will hold reformatted data that is more suitable for analysis and presentation. Being able to take existing text and numeric data and store it in alternative forms is often vital for working with this information through symbology, labeling, geoprocessing, and other common operations. However, when it comes to Date or Date-Time fields, the Python methods provided by the Field Calculator are limited to manipulating the current system date or time or the parsed date components (year, month, day, hour, minute, second, AM/PM) that make up a date, not a date itself. The methods provided are of no real use for parsing, manipulating and transforming dates or times that have been stored in a Date/Date-Time field. The help documentation for the Field Calculator provides numerous examples of existing text and numeric fields, but is completely silent on how to apply any of the available Python date methods to dates stored in a date field. As a result, beyond using the actual date value itself, few users know how to extract information from the values stored in a date field that would let them fully analyze and present their date-based data in the most effective way through the ArcGIS software. The purpose of this Blog is to try to tackle the challenges of parsing, manipulating and transforming values stored in date fields or text fields holding date-based data using Python and the ArcGIS Field Calculator. Some challenges in tackling date field values are specific to the use of Python in the Field Calculator, and could be handled relatively easily by using a VB Script Field Calculation alternative or exporting to Excel and using the formulas of that program. However, this Blog will limit itself to offering a pure ArcGIS/Python solution, even where the ArcGIS/Python solution is a fair amount more difficult to implement than the VB Script calculation or an Excel formula. 2. Why is it important to be able to manipulate Date-Time fields and text fields with date-based data in ArcGIS? Since ArcGIS 10.1, all products of the GIS software have included the ability to apply time awareness to user data. However, often this data does not comply with the standards required to make good use of the time aware features of ArcGIS. For example, time aware data must naturally sort in its native type according to datetime sorting rules, and often an alphabetical sort of data stored as text violates the patterns of a true datetime value sort. Even if you have your data stored in a Date-Time field and it can be sorted, it is most often stored as the local datetime value of the data provider. However, if that data ever needs to be compiled with data in other time zones it will need to be standardized to a universal datetime, such as UTC, before it can be integrated with data coming from outside of that local datetime representation and used with the time aware features of ArcGIS. Also, although the ArcGIS software continues to expand the available geoprocessing tools that can make your data more suitable for use with its time aware capabilities, much of the processing still only takes places on the fly in conjunction with the ArcGIS time slider. But in many cases, it is often more convenient if the datetime data has been recalculated into a field that has converted the datetime into periods of different multiples or divisions of years, quarters, months, days of the month, etc, so that the date-based data can be easily summarized into a table format for reports or easily used within a geoprocessing workflow. The time aware features of ArcGIS also do not readily handle all datetime periods, such as divisions of a year into pay period cycles, the natural seasons of winter, summer, spring and autumn, lunar cycles, etc. all of which can be derived from a datetime value rather than typed by a user. Being able to convert a datetime value into custom or natural time period divisions or groupings can be essential to fully analyzing hidden relationships within time-based data and invaluable to let you take advantage of the full range of ArcGIS capabilities for presenting that data. 3. When is a Date or a Date-Time Field Value neither a Date nor a DateTime? Unfortunately, the answer to this section's question is "when it is a Unicode String", which is what is returned by a Date or Date-Time field when the Field Calculator is set to use the Python parser option. This is a peculiarity of a Python field calculation, since If you are using a cursor in a Python script the value returned by a date field will be a date or datetime variable and not a Unicode string The most likely reason a Unicode String is returned is that the field calculator interface is closely related to the labeling expression interface. When a date field is used to create a label the returned formatted date string ensures that a user-friendly date will appear in the label without using any other Python code. If a Python Date or DateTime variable was returned, the label would not appear in a user-friendly format without specifying a format through a method like datetime.strptime(). At least in the case of Windows-based systems, the format of the date string is specified in the OS Settings and is controlled by one or both of the OS Short Date and OS Long Time settings. Users of other operating systems will have to verify for themselves where the setting that controls the date format string can be found. The OS short date setting controls both the way the date will appear in the Table Window and the format of the string provided from a date field to a Python Field Calculation. Because different cultures use different short date and long time formats and each culture has multiple short date and long time formats to choose from, the conversion of the string to an actual date or datetime variable that can be easily manipulated to extract date information is the biggest challenge that has to be overcome in order to use the Field Calculator with the Python option. 4. Windows and Python format codes used to parse date and/or time strings The format strings for the US & Canada region default Windows short date format is "M/d/yyyy" which equates to the Python format u'%m/%d/%Y' (i.e, u'12/25/2016'). The format strings for the US & Canada region default Windows long time format is 'h:mm:ss tt' which equates to the Python format u'%I:%M:%S %p' (i.e., u'1:52:20 PM'). The Python formats would need to change if you have selected an incompatible alternative format, or if you have regional settings that use a different format setting than the US & Canada default short date and long time formats. The Windows and Python equivalent formats for the common date or time components are: MM or M = %m (Month number with or without a leading zero) MMM = %b (Month as locale’s abbreviated name) MMMM = %B (Month as locale’s full name) dd or d = %d (Day of the month number with or without a leading zero) ddd = %a (Weekday as locale’s abbreviated name) dddd = %A (Weekday as locale’s full name) yy or y = %y (Year number without century with or without a leading zero) yyyy = %Y (Year number with century) hh or h = %I (Hour (12-hour clock) with or without a leading zero) HH or H = %H (Hour (24-hour clock) with or without a leading zero) mm or m = %M (Minute number with or without a leading zero) ss or s = %S (Second number with or without a leading zero) tt = %p (Locale’s equivalent of either AM or PM) /, -, : = /, -, : (literal date or time separator characters) Be sure to pay attention to the case of each Windows or Python code, since uppercase codes and lowercase codes parse different date or time components. If you are using an OS other than Windows you will have to determine the equivalents between the format codes your OS uses and those Python uses to match your OS' short date and long time formats. The full set of Windows US & Canada short date and long time codes and their Python code equivalents are shown below: 5. A Field Calculator calculation for parsing a formatted date and/or time in a Text field or a Date or Date-Time field and convert it into a Python datetime variable. The date value formats that are provided to a Python Field Calculation from a Date or Date-Time field include Null values (Python==None), short date, short date and time, and time only (which occurs if the date is 12/30/1899 in a file gdb). This also often applies to text fields that store a date and/or time if users have been well trained or use a front end validation interface to enter data. The code I have designed is intended to deal with each possibility. To do the parsing I will be using datetime.strptime method which attempts to parse a Unicode string into a datetime based on the specified date and time format strings. Open the Field Calculator on a blank date field (right-click the field name in the output column in a table and choose Field Calculator from the context menu) and set the Field Calculator to the following settings: Parser: Python Show Codeblock: Checked Pre-Logic Script Code: def unicodeToDate( uniDate, dateFormat=u'%m/%d/%Y', timeFormat=u'%I:%M:%S %p' ):
datetimeFormat = '{0} {1}'.format(dateFormat, timeFormat)
if uniDate == None:
return None
try:
return datetime.datetime.strptime(uniDate, dateFormat)
except:
try:
return datetime.datetime.strptime(uniDate, datetimeFormat)
except:
try:
# Python parses time only values as 1/1/1900 so subtract 2 days to match 12/30/1899, the date a file gdb uses.
return datetime.datetime.strptime(uniDate, timeFormat) + timedelta(days=-2)
except:
return None Expression: unicodeToDate( !Your_Date_Field!, dateFormat = u'%m/%d/%Y' , timeFormat = u'%I:%M:%S %p' ) Be sure to replace !Your_Date_Field! with a real Date/Date-Time/Time field or Text field containing dates and/or times. The number of embedded try-except blocks can be expanded to include other formats. This can be useful when attempting to convert a text field with multiple date and/or time formats into a true date field. The conversion of all of the formats can be done by a single calculation as long as the order of the try-except blocks are arranged to test for the most common formats to the least common formats from top to bottom. 6. A Field Calculation that can return many different derived date components from the datetime variable returned by the calculation in Step 5. Date fields have many components that can derived from the datetime values, and I prefer to use a single calculation to get at them all rather than many separate calculations. This saves me from having to load many different .cal files and replace the date field used by each calculation to get a different date component. The Calculation below uses a partIndex value ranging from 0-25 to get any of 26 components from any date field that can be parsed by the calculation in step 5. (These calculations work for Python 2.7, but some may need to be changed to work for Python 3.4.x used by the latest version of ArcGIS Pro.) Open the Field Calculator on a blank numeric field with a date component name like Year_ (right-click the field name in the output column in a table and choose Field Calculator from the context menu) and set the Field Calculator to the following settings: Parser: Python Show Codeblock: Checked Pre-Logic Script Code: def dateFieldPart( uniDate , partIndex = 8 , dateFormat = u'%m/%d/%Y' , timeFormat = u'%I:%M:%S %p' , offsetStartYear = 0 ):
# use the def defined in the previous field calculation which is included in this new calculation
theDate = unicodeToDate( uniDate, dateFormat=u'%m/%d/%Y', timeFormat=u'%I:%M:%S %p' )
# if the unicode could not be parsed to a datetime return None, otherwise use the partIndex specified by the user to return one of many different derived components of a datetime.
if theDate == None:
return None
try:
if partIndex == 0: # century (100-year periods-returns period start year-default is 00)
return theDate.year - ((theDate.year + (100 - (offsetStartYear % 100) % 100)) % 100)
elif partIndex == 1: # half-century (50-year periods-returns period start year-defaults end in 00 and 50)
return theDate.year - ((theDate.year - (50 - (100 - (offsetStartYear % 50)) % 50)) % 50)
elif partIndex == 2: # quarter-century (25 year periods-returns period start year-defaults end in 00, 25, 50, 75)
return theDate.year - ((theDate.year - (25 - (100 - (offsetStartYear % 25)) % 25)) % 25)
elif partIndex == 3: # decade (10 year periods-returns period start year-defaults end in 00, 10, 20, 30, ... 90)
return theDate.year - ((theDate.year - (10 - (100 - (offsetStartYear % 10)) % 10)) % 10)
elif partIndex == 4: # lustrum (5-year periods-returns period start year-defaults end in 00, 05, 10, 15, ... 95)
return theDate.year - ((theDate.year - (5 - (100 - (offsetStartYear % 5)) % 5)) % 5)
elif partIndex == 5: # quadrennium (4-year periods-returns period start year-defaults end in 00, 04, 08, 12, ... 96)
return theDate.year - ((theDate.year - (4 - (100 - (offsetStartYear % 4)) % 4)) % 4)
elif partIndex == 6: # triennium (3-year periods-returns period start year-defaults end in 00, 03, 06, 09, ... 97 over a 300 year cycle)
return theDate.year - ((theDate.year - (3 - (300 - (offsetStartYear % 3)) % 3)) % 3)
elif partIndex == 7: # biennium (2-year periods-returns period start year-defaults end in 00, 02, 04, 06, ... 98)
return theDate.year - ((theDate.year - (2 - (100 - (offsetStartYear % 2)) % 2)) % 2)
elif partIndex == 8: # year
return theDate.year
elif partIndex == 9: # fiscal year (year-1 for January-June and year for July-December)
return theDate.year-(abs(theDate.month-13))//7
elif partIndex == 10: # semiannual (six-month periods, with first 6 months = 1 and second 6 months = 2)
return (theDate.month - 1)//6 + 1
elif partIndex == 11: # calendar quarter
return (theDate.month - 1)//3 + 1
elif partIndex == 12: # fiscal quarter
return ((theDate.month + 5)%12)//3 + 1
elif partIndex == 13: # month of year
return theDate.month
elif partIndex == 14: # month of year percent (January=0% and 99%<December<100%)
return float(float(theDate.month - 1) / 12) * 100.0
elif partIndex == 15: # day of year number (1-365 for non-leap years and 1-366 for leap years)
return theDate.timetuple().tm_yday
elif partIndex == 16: # day of year percent (January 1 = 0% and 99% < December 31 < 100%)
return float(float(theDate.timetuple().tm_yday - 1) / datetime.datetime(theDate.year, 12, 31).timetuple().tm_yday) * 100.0
elif partIndex == 17: # day of month
return theDate.day
elif partIndex == 18: # ISO week of the year (1-52 or 1-53)
return theDate.isocalendar()[1]
elif partIndex == 19: # day is weekday/weekend (0=Weekday and 1=Weekend)
return theDate.weekday()//5
elif partIndex == 20: # day of week (0=Monday to 6=Sunday)
return theDate.weekday()
elif partIndex == 21: # day of week (0=Sunday to 6=Saturday)
return (theDate.weekday()+1) % 7
elif partIndex == 22: # season northern hemisphere
return get_season(theDate)
elif partIndex == 23: # season southern hemisphere
return (get_season(theDate) + 1) % 4 + 1
elif partIndex == 24: # moonlight percent approximate (0=no moonlight to 100=max. moonlight),
return moon_light(theDate, 0)
elif partIndex == 25: # moon phase approximate
return moon_light(theDate, 1)
except:
return None
def unicodeToDate( uniDate, dateFormat=u'%m/%d/%Y', timeFormat=u'%I:%M:%S %p' ):
datetimeFormat = '{0} {1}'.format(dateFormat, timeFormat)
if uniDate == None:
return None
try:
return datetime.datetime.strptime(uniDate, dateFormat)
except:
try:
return datetime.datetime.strptime(uniDate, datetimeFormat)
except:
try:
# Python parses time only values as 1/1/1900 so subtract 2 days to match 12/30/1899, the date a file gdb uses.
return datetime.datetime.strptime(uniDate, timeFormat) + datetime.timedelta(days=-2)
except:
return None
# Approximate ranges defining seasons only. Not precise. Use a site-package like PyEphem for precision.
Y = 2000 # dummy leap year to allow input X-02-29 (leap day)
seasons = [(1, (datetime.date(Y, 1, 1), datetime.date(Y, 3, 20))),
(2, (datetime.date(Y, 3, 21), datetime.date(Y, 6, 20))),
(3, (datetime.date(Y, 6, 21), datetime.date(Y, 9, 22))),
(4, (datetime.date(Y, 9, 23), datetime.date(Y, 12, 20))),
(1, (datetime.date(Y, 12, 21), datetime.date(Y, 12, 31)))]
def get_season(dDate):
dDate = datetime.date(Y, dDate.month, dDate.day)
return next(season for season, (start, end) in seasons
if start <= dDate <= end)
# Approximate moon light and phase only. Not precise. Use a site-package like PyEphem for precision.
def moon_light(dDate, moon_type=0):
# moon_type is: 0=moonlight percent, 1=moon phase
month = dDate.month
day = dDate.day
year = dDate.year
ages = [18, 0, 11, 22, 3, 14, 25, 6, 17, 28, 9, 20, 1, 12, 23, 4, 15, 26, 7]
offsets = [-1, 1, 0, 1, 2, 3, 4, 5, 7, 7, 9, 9]
description = ['New (Totally dark)',
'Waxing Cresent (Increasing to full)',
'In its first quarter (Increasing to full)',
'Waxing Gibbous (Increasing to full)',
'Full (Full light)',
'Waning Gibbous (Decreasing from full)',
'In its last quarter (Decreasing from full)',
'Waning Cresent (Decreasing from full)']
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
if day == 31:
day = 1
days_into_phase = ((ages[(year + 1) % 19] +
((day + offsets[month-1]) % 30) +
(year < 1900)) % 30)
index = int((days_into_phase + 2) * 16/59.0)
if index > 7:
index = 7
status = description[index]
# light should be 100% 15 days into phase
light = int(2 * days_into_phase * 100/29)
if light > 100:
light = abs(light - 200);
date = "%d%s%d" % (day, months[month-1], year)
if moon_type == 0:
return light
elif moon_type == 1:
return index
elif moon_type == 2:
return status Expression: dateFieldPart( !Your_Date_Field! , partIndex = 8 , dateFormat = u'%m/%d/%Y' , timeFormat = u'%I:%M:%S %p' , offsetStartYear = 0 ) Be sure to replace !Your_Date_Field! with a real Date/Date-Time field or Text field containing dates or date-times. Although the calculation above will convert a real Time field or Text field containing time, only values derived from the date associated with the time value (i.e., 12/30/1899) will be returned. The partindex parameter determines the kind of data that will be derived from the date and returned by the calculation. Since the partIndex = 8 in this example, the Expression above will convert the field date to a Python datetime variable and return the Year of that value in each record. If you change the partIndex to another number a different date component will be outputted. For example, if you change the partIndex parameter to partIndex = 0 the calculation will convert the field date to a Python datetime variable and return the Century of that value in each record. The offsetStartYear parameter affects the year grouping values returned by partIndexes 0 through 7. It adjusts the start year that begins the period interval to a custom starting year. This can be used to satisfy those who need to mark the start of centuries from year 1, and regard the 21st century as having started on 2001, not 2000. By default the function returns centuries based on a year 0 starting year due to the mathematical simplicity of computing that value and its popular usage. To make centuries aligned to the Year 1 as the century starting point instead, use partIndex = 0 and offsetStartYear = 1 as your parameters. Other less traditional starting years can also be used. For example, by setting partIndex = 0 and offsetStartYear = 50 you can define periods of 100 years (centuries) that extend from one mid-century to the next mid-century according to popular reckoning, rather than a traditional century. Year 1 advocates can similarly use offsetStartYear = 51 to align their custom century groupings to the year that they regard as the mid-century start year. Other calculations are possible, for example I used a very simple method of estimating seasons and moon phases, but those methods could be replaced with methods that use a site package like PyEphem to return very precise values. Or I could add an option for a custom 2 week pay period cycle, primary seasonal year so that December to March seasons avoid being separated across different calendar years, or other custom groupings or divisions of years, months, day, week, hours, minutes, seconds, etc. 7. A sample time-based animation demo video showing some of what you can do using the calculation. Here is a link to a YouTube video of a time based animation demo I created that shows the importance of being able to manipulating date fields to create alternative formats and date groupings. This time based animation was only possible after I used my calculation to transform my original Applied_Date field into an Applied_Fiscal_Year Long field for some of my building permits data The new field let me symbolize each Fiscal Year with a distinct color using categorized symbols. The new field also let me Dissolve the permits to get a Count of the Permits in each Fiscal Year. The Dissolve allowed me to create labels on the map showing the counts and a time based graph of the permit activity by Fiscal Year. The Dissolve also dramatically improved the redraw performance over my original data. Below are a three screenshots from the demo that shows different stages of building permit activity over time using both a time enabled map and a linked bar chart graph. 8. Please let me know any feedback you may have. If you discover any errors in the formulas I have used in my calculations or can suggest an alternative formula that is more Pythonic or that makes the code more efficient/flexible, please let me know, so that I can incorporate your corrections/suggestions into the calculations of this Blog for the benefit of everyone. Also if you identify any changes that need to be made to allow these calculations to be compatible with ArcGIS Pro/Python 3.4.x and above, please let me know. I hope to eventually update this Blog with additional versions of the calculations that have been tested for compatibility and optimized for use with ArcGIS Pro/Python 3.4.x and above. I hope this helps you uncork your Time in a Bottle. Revisions: Corrected formula for the case when the only the timeFormat parses the date on 7/2/2016 at 8:26 AM PST. Corrected offsetStartYear formulas on 7/2/2016 8:26 AM PST. Corrected descriptions of formulas that use offsetStartYear on 7/2/2016 12:50 PM PST and 7/3/2016 8:06 AM PST.
... View more
07-01-2016
08:56 AM
|
10
|
6
|
5544
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-24-2026 11:37 PM | |
| 1 | 03-24-2026 08:01 PM | |
| 6 | 02-23-2026 08:34 AM | |
| 1 | 03-31-2025 03:25 PM | |
| 1 | 03-28-2025 06:54 PM |
| Online Status |
Offline
|
| Date Last Visited |
Saturday
|