Wolfram Geography :
 Historical Computation

Cesar Loli, WRSA

(RowDefault[, (Spacer1), , (Spacer1), ])  #WolframTechConf

Geographical Computation with Historical Data

Extend Wolfram Language Geo computational capabilities to include historical information from the WolframAlpha’s Knowledgebase.

Make better maps and charts that are more didactic and informative about historical topics.

Perform large computations using historical and geographical data in order to locate historical events, people or organizations in both time and space.

Historical Maps

There are now three new properties that will allow the user to engage with historical maps. The first would be how EntityValue works with time series of polygons:

ts=Dated[(Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"]),All]["Polygon"]

DateListStepPlot@TimeSeriesMap[GeoArea,ts]

GeoGraphics[{Blue,ts[(DateObject["Year: ""255", DateObject[{255},"Year"]])],Red,ts[(DateObject["Year: ""272", DateObject[{272},"Year"]])]},GeoBackground->"Coastlines"]

Historical Maps: MaximumExpansion

“MaximumExpansionDate” will correspond to the maximum extent reached for a given country:

year= (Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"])["MaximumExpansionDate"]

GeoGraphics[GeoVariant[(Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"]),"MaximumArea"]["Polygon"],GeoBackground->Dated["CountryBorders",year]]

We can use Dated to narrow down the range of years in which we will be searching for its maximum area:

year= Dated[(Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"]),{270,274}]["MaximumExpansionDate"];
GeoGraphics[GeoVariant[Dated[(Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"]),{270,274}],"MaximumArea"]["Polygon"],GeoBackground->Dated["CountryBorders",year]]

Historical Maps: UnionPolygon

“UnionPolygon” is a property that will represent all the territories once occupied by that nation, i.e. the union of all the polygons assigned to it:

allRomanAreas=GeoPolygon[GeoVariant[(Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"]),"UnionArea"]];
romanMaximumExpansion=GeoPolygon[GeoVariant[(Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"]),"MaximumArea"]];

GeoListPlot[{{allRomanAreas},{romanMaximumExpansion}},GeoBackground->"Coastlines",PlotLegends->{"UnionArea","MaximumArea"}]

We can use Dated to narrow down the results so we are returned all the territories once occupied by that nation in that given period of time:

GeoGraphics[Dated[(Entity[(RowWithSeparator[ , "Roman Empire", (EntitySublabel["27 BC \[Hyphen] 395 AD"])]), Entity["HistoricalCountry","RomanEmpire"], "Entity[\"HistoricalCountry\", \"RomanEmpire\"]", "historical country"]),{270,274}]["UnionPolygon"],GeoBackground->"Coastlines"]

Geographical and Historical Computations

We can use the geographical functions present in Wolfram Language to learn things for a particular location like the country a certain city is located in:

GeoIdentify["Country",(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"])]

Or its more specific administrative divisions:

GeoIdentify["AdministrativeDivision",(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"])]

Now, it has the capability to extend this geographical computation into other eras of history:

GeoIdentify["HistoricalCountry",(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"])]

Using the Dated wrapper we can narrow down the desired result to a more specific date:

GeoIdentify["HistoricalCountry",Dated[(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"]),600]]

Geographical and Historical Computations

romeTimeline=GeoIdentify[Dated["HistoricalCountry",All],(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"])];

Short@romeTimeline

TimelinePlot[Reverse/@Rule@@@romeTimeline]

DateInterval can be used as input in order to narrow down the desired calculation to a specific time like the early middle ages:

medievalInterval=DateInterval@(Entity["Early Middle Ages", Entity["HistoricalPeriod","EarlyMiddleAges"], "Entity[\"HistoricalPeriod\", \"EarlyMiddleAges\"]", "historical period"])[{(EntityProperty["start date", EntityProperty["HistoricalPeriod","StartDate"], "EntityProperty[\"HistoricalPeriod\", \"StartDate\"]"]),(EntityProperty["end date", EntityProperty["HistoricalPeriod","EndDate"], "EntityProperty[\"HistoricalPeriod\", \"EndDate\"]"])}]

romeMedievalTimeline=GeoIdentify[Dated["HistoricalCountry",medievalInterval],(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"])];

Short@romeMedievalTimeline

TimelinePlot[Reverse/@Rule@@@romeMedievalTimeline]

Geographical and Historical Computations

GeoNearest can be used to locate the nearest military conflicts to the city of Rome:

battlesNearRome=GeoNearest["MilitaryConflict",(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"]),10]

GeoListPlot[battlesNearRome]

GeoIdentify can then be used to identify in which historical countries each conflict occurred:

GeoIdentify[Dated["HistoricalCountry",All],battlesNearRome]

GeoEntities can be then used to find which historical countries formed part of Italy at the time of one of the conflicts we calculated before:

Short[countriesDuringVelletri=GeoEntities[(Entity["Italy", Entity["Country","Italy"], "Entity[\"Country\", \"Italy\"]", "country"]),Dated["HistoricalCountry",(Entity["Battle of Velletri", Entity["MilitaryConflict","BattleOfVelletri1744"], "Entity[\"MilitaryConflict\", \"BattleOfVelletri1744\"]", "military conflict"])["StartDate"]]]]

GeoListPlot[#,PlotLegends->EntityValue[#[[All,1,1]],"Name"],GeoBackground->"CountryBorders",GeoRange->(Entity["Italy", Entity["Country","Italy"], "Entity[\"Country\", \"Italy\"]", "country"])]&@(List/@Normal@countriesDuringVelletri)

Giving historical support to other geographic computations

TravelDirections can be used to get the path between two geographic locations:

td=TravelDirections[{(Entity["Rome", Entity["City",{"Rome","Lazio","Italy"}], "Entity[\"City\", {\"Rome\", \"Lazio\", \"Italy\"}]", "city"]),(Entity["Paris", Entity["City",{"Paris","IleDeFrance","France"}], "Entity[\"City\", {\"Paris\", \"IleDeFrance\", \"France\"}]", "city"])},TravelMethod->"Walking"];

td["TravelPath"]

Then use GeoIdentify to calculate over which historical countries the given path would go through on a certain given date:

GeoIdentify[Dated["HistoricalCountry",-300],td["TravelPath"]]

GeoIdentify[Dated["HistoricalCountry",100],td["TravelPath"]]

GeoIdentify[Dated["HistoricalCountry",1300],td["TravelPath"]]

Giving historical support to other geographic computations

Other geographical functions may be use such as one that calculate the trajectories and visibility of historical eclipses. For example we can use the one observed by Thales in 585 BC:

eclipse=SolarEclipse[(DateObject["Year: ""585 BC", DateObject[{-585},"Year"]]),EclipseType->"Total"]

umbra=SolarEclipse[eclipse,"UmbraEnvelopePolygon"]

GeoGraphics[umbra]

startDate=SolarEclipse[eclipse,"ContactPointU1Date"]

endDate=SolarEclipse[eclipse,"ContactPointU4Date"]

eclipseDateRange=DateRange[startDate,endDate,{1,"Minute"}];

eclipseTimeSeries=Cases[{SolarEclipse[eclipse,{"UmbraPolygon",#}],#}&/@eclipseDateRange,{GeoPolygon[p:GeoPosition[{__}]],d_DateObject}:>Dated[Polygon@p,d]];

countriesInEclipse=GeoIdentify[Dated["HistoricalCountry",All],eclipseTimeSeries];

countriesInEclipseGrouped=DateInterval/@MinMax/@GroupBy[Flatten[countriesInEclipse],First->Last];

Dataset[countriesInEclipseGrouped]

datedCountriesInEclipse=Thread[Dated[Keys[countriesInEclipseGrouped],DateObject[{-585}]]]

GeoGraphics[{Polygon/@datedCountriesInEclipse,Red,umbra},GeoBackground->Dated["CountryBorders",-585],GeoRange->datedCountriesInEclipse,GeoZoomLevel->4]