Sign in




Creation date Thurs 12 Febraury 2015
Creator flynam
Last modified Thurs 12 Febraury 2015
Code Bitbucket
Data mining pptextiles

The textiles project looks at the geospatial distribution of the nearly 200 loomweights that were found at Priniatikos Pyrgos. The user is able to plot a heatmap of these find spots on a plan of the site. The heatmap can be filtered by loomweight type and/or by the assigned period of the find.

Technically, the website is built on a familiar combination of web client-side technologies. The jQuery library is employed to send AJAX HTTP calls to the SPARQL interface (sparql.php).


The SPARQL query is constructed as follows:

PREFIX ecrm: <>
PREFIX crmeh: <>
PREFIX rdfs: <>
PREFIX la_vocabs: <>
PREFIX la_pp: <>

SELECT ?find ?type ?geoPoly WHERE {
	?find a crmeh:EHE0009_ContextFind .
	?find rdfs:name ?name .
	?find ecrm:P2_has_type la_vocabs:object-loomweight .
	?find ecrm:P2_has_type ?type .
	?find ecrm:P89_falls_within ?context .
	?context ecrm:P87_is_identified_by ?geoPoly .
	FILTER(DATATYPE(?geoPoly) = crmeh:EHE0022_ContextDepiction) . {
		?find ecrm:P2_has_type la_vocabs:loomweight-pyramidal
	} UNION {
		?find ecrm:P2_has_type la_vocabs:loomweight-conical

As you can see, it uses a number of ontologies and vocabularies that are shortened to prefixes listed at the start of the query. The first of these, which goes by the prefix ecrm is the base URI of the CIDOC CRM ontology and is needed because it is the CRM that the Priniatikos Pyrgos dataset is fundamentally built upon. The next prefix listed, crmeh, points to the English Heritage CRM extension, which was created by EH to model data derived from single-context archaeological excavation and recording. The Priniatikos Pyrgos project employed a single-context methodology from 2007-2010 but the crmeh model is generic enough to allow for the modelling of the pre-2007 excavation data as well, which was recorded using the locus-pail method. However, this and other slight idiosyncrasies of the project’s single-context implementation required the extension of the crmeh (note that these extensions are not employed or indeed needed in the loomweights case).

The prefixes la_vocabs and la_pp point to URI bases that deal with data unique to the knowledge domain. la_vocabs prefixes all of the custom vocabularies used by and la_pp points to data nodes within the Priniatikos Pyrgos dataset.

Line 7 lists the SELECT command, which is integral to most SPARQL queries. It is analogous to the SQL SELECT command and in this case it asks the engine to select out of all the variables contained within the following query only the ones listed. So, in this case, we are interested in the ?find, ?type and ?geoPoly variables.

Lines 8-18 lay out the series of triple patterns that make up the query. Each line contains a discreet query in itself and it is logically ANDed (when the triple is followed by a period) or ORed (when followed by a UNION keyword) with the rest of the triples.

So in our case, line 8 asks for all the subjects that have an rdfs:type object of crmeh:EHE0009_ContextFind. The rdfs:name object for each of these subjects is stored in ?name. We then narrow down the query on line 10 to only include subjects that have a ecrm:P2_has_type object of la_vocabs:object-loomweight. The ecrm:P2_has_type predicate, as with many RDF predicates, can contain multiple objects and so we store all of these for our subject in ?type.

We now want to get the geo-coordinates of the context or locus in which the find was made. To get to this parent context or locus we check the ecrm:P89_falls_within predicate and store its object in ?context. Then to get to the geo-coordinates we check ecrm:P87_is_identified_by but we filter the objects in this triple pattern because we only want those with the type crmeh:EHE0022_ContextDepiction. ecrm:P87_is_identified_by also can contain links to multiple objects and these objects can be of different types and that’s why we need to include the FILTER statement.

Finally, we want to refine the result-set down again to only include those finds that have an ecrm:P2_has_type object of la_vocabs:loomweight-pyramidal or la_vocabs:loomweight-conical. We achieve the logical OR by linking these two triples with the UNION keyword.

Running this SPARQL query will return the subject URI, the loomweight type and a string containing a KML polygon locating on the site each find that is of the specified loomweight type.

Making a zoomable and panable map of the site

Before you can plot locations on a plan, you need to generate a digital plan. There are many ways of plotting a graphical plan such as topographic map onto a mapping system – you could use a Google Maps overlay for instance. However, I chose to achieve this effect using the MapTiler app and the Leaflet JavaScript library for mapping as it produces a very smooth and professional looking result.

MapTiler is pretty easy to use and it generates HTML and JS outputs using a variety of different underlying mapping libraries, so it is fairly straighforward to get it up and running. MapTiler also allows you to geo-rectify your input image, which is great as otherwise, you would need to transform the WGS84 longitude and latitude values returned by the SPARQL call into a local projection system.

Leaflet is built around the layers structural concept. It is very easy to set up a map with more than one layer and that is exactly what I did for the Priniatikos Pyrgos Textiles Project. I added a basic world map layer, whose tile data comes from OpenStreetMap. On top of this I added the tiles for the plan of the site, which MapTiler generated. Finally, I added a heatmap layer, which I will discuss in the context of the plotting of the finds next.

Plotting the finds

Finally, you have to plot the finds on the map and I chose to do this using a heatmap effect, as it creates what I consider to be a more readable visualisation of distribution patterns across space. Thankfully, Leaflet allows you to select from a list of 3rd party plugins, a number of which render a heatmap effect. The most popular of these seems to be Patrick Wied’s Heatmap plugin and despite a couple of issues at the start (like there being no explicit way to clear the heatmap of data), I managed to get it up and running.

Wied’s plugin accepts a JS object that is defined as follows:

	max: 100,
	data: [{lat: 0, lng:0, count: 0}]

This is passed to the plugin using the heatmap.setData() method.


And that’s it. The Priniatikos Pyrgos Textiles Project is a fairly simple single-function web site but there are a lot of advantages to this approach and it seems that this sort of targeted exercise is the way that many Digital Humanities projects are currently formulating their research questioning. The same logic could be used to plot all of the lithics found at Priniatikos Pyrgos or to consider how one find types find type compares against another across time. The only limit is your imagination.