query-8ca8cb23dade729c170f8128e9ffbd86

rq turtle/ttl

geoshapes coloured by their distance from a central point

Use at

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX bd: <http://www.bigdata.com/rdf#>
# geoshapes coloured by their distance from a central point
#defaultView:Map{"hide":["?geoshape","?rgb"]}
SELECT ?x ?xLabel ?description ?geoshape ?rgb  # determine the max and min values (used to calculate the spread
WHERE {
   {
# extract the data
SELECT ?data ?x ?geoshape $CENTRE WHERE {
  VALUES $CENTRE { wd:Q84 }
  $CENTRE wdt:P625 $CENTRE_COORDS .
  BIND (1000 AS $LIMIT) 
  ?x wdt:P3896 ?geoshape .
  ?x wdt:P17 wd:Q145 .
  ?x wdt:P625 ?x_coords .
  # exclude items that obscure smaller areas
  FILTER (?x NOT IN (wd:Q145, wd:Q22, wd:Q21, wd:Q25, wd:Q26))
  BIND(geof:distance($CENTRE_COORDS, ?x_coords) as ?data) 
  FILTER (?data < $LIMIT)
  }
}   { 
  SELECT (MAX(?data) AS ?max_data)  (MIN(?data) AS ?min_data) WHERE {
   {
# extract the data
SELECT ?data ?x ?geoshape $CENTRE WHERE {
  VALUES $CENTRE { wd:Q84 }
  $CENTRE wdt:P625 $CENTRE_COORDS .
  BIND (1000 AS $LIMIT) 
  ?x wdt:P3896 ?geoshape .
  ?x wdt:P17 wd:Q145 .
  ?x wdt:P625 ?x_coords .
  # exclude items that obscure smaller areas
  FILTER (?x NOT IN (wd:Q145, wd:Q22, wd:Q21, wd:Q25, wd:Q26))
  BIND(geof:distance($CENTRE_COORDS, ?x_coords) as ?data) 
  FILTER (?data < $LIMIT)
  }
}           
 }
}  
  ?x rdfs:label ?xLabel. FILTER (LANG(?xLabel) = "en") .
  $CENTRE rdfs:label $CENTRELabel. FILTER (LANG($CENTRELabel) = "en") .

  BIND (CONCAT("The centre of ", ?xLabel, " is about ", STR(ROUND(?data)), " kilometres from the centre of ", $CENTRELabel  ) AS ?description) 
  BIND ( ?max_data - ?min_data AS ?spread )
  BIND ( xsd:integer( 100 * (?data - ?min_data) / ?spread) AS ?percent ) # 0 -> 100 
# some example hues 0:red, 20:orange, 50:yellow, 90:green, 180:cyan, 220:blue, 280:indigo, 330:violet, 340:red
# varying hue        
#   BIND ( 255 * ?percent / 100 + 0 AS ?hue ) 
#   BIND (1 AS ?value) # 
#   BIND (1 AS ?saturation) . # 0 -> 1
# varying the hue's value
  BIND ( (1 - ?percent / 100 + 0) AS ?value ) # to black
  BIND (90 AS ?hue) # green
  BIND (1 AS ?saturation) . # 0 -> 1
# varying the hue's saturation
#   BIND ( (1 - ?percent / 100 + 0) AS ?saturation ) # to -> white
#   BIND (90 AS ?hue) # green
#   BIND (1 AS ?value) . # 0 -> 1  
# the following algorithm based on https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
  BIND ( ?hue / 60 AS ?hh )
  BIND ( FLOOR (?hh) AS ?i ) .
  BIND ( ?hh - ?i  AS ?ff) .
  BIND ( ?value * ( 1 - ?saturation ) AS ?p) .
  BIND ( ?value * ( 1 - ( ?saturation * ?ff)) AS ?q ) .
  BIND ( ?value * ( 1 - ( ?saturation * (1 - ?ff ))) AS ?t ) . 
  BIND ( COALESCE(
    IF(?i = 0, ?value, 1/0),
    IF(?i = 1, ?q, 1/0),
    IF(?i = 2, ?p, 1/0),
    IF(?i = 3, ?p, 1/0),
    IF(?i = 4, ?t, 1/0),
    IF(?i = 5, ?value, 1/0),
    ?value
  ) AS ?r )
  BIND ( COALESCE(
    IF(?i = 0, ?t, 1/0),
    IF(?i = 1, ?value, 1/0),
    IF(?i = 2, ?value, 1/0),
    IF(?i = 3, ?q, 1/0),
    IF(?i = 4, ?p, 1/0),
    IF(?i = 5, ?p, 1/0),
    ?p
  ) AS ?g )
  BIND ( COALESCE(
    IF(?i = 0, ?p, 1/0),
    IF(?i = 1, ?p, 1/0),
    IF(?i = 2, ?t, 1/0),
    IF(?i = 3, ?value, 1/0),
    IF(?i = 4, ?value, 1/0),
    IF(?i = 5, ?q, 1/0),
    ?q
  ) AS ?b )
  BIND (FLOOR(255 * ?r) AS ?red) 
  BIND (FLOOR(255 * ?g) AS ?green)  
  BIND (FLOOR(255 * ?b) AS ?blue)
  # red
  BIND ( FLOOR (?red / 16) AS ?red_1 )
  BIND ( COALESCE(
    IF(?red_1 < 10, STR(?red_1), 1/0),
    IF(?red_1 = 10, "a", 1/0),
    IF(?red_1 = 11, "b", 1/0),
    IF(?red_1 = 12, "c", 1/0),
    IF(?red_1 = 13, "d", 1/0),
    IF(?red_1 = 14, "e", 1/0),
    IF(?red_1 = 15, "f", 1/0),
    "ERROR"
  ) AS ?red_hex1 )
  BIND (FLOOR(?red - (16 * xsd:integer( ?red / 16 ))) AS ?red_2)
  BIND ( COALESCE(
    IF(?red_2 < 10, STR(?red_2), 1/0),
    IF(?red_2 = 10, "a", 1/0),
    IF(?red_2 = 11, "b", 1/0),
    IF(?red_2 = 12, "c", 1/0),
    IF(?red_2 = 13, "d", 1/0),
    IF(?red_2 = 14, "e", 1/0),
    IF(?red_2 = 15, "f", 1/0),
    "ERROR"
  ) AS ?red_hex2 )
  BIND (CONCAT(STR(?red_hex1), STR(?red_hex2)) AS ?red_hex )
  # green
  BIND ( FLOOR (?green / 16) AS ?green_1 )
  BIND ( COALESCE(
    IF(?green_1 < 10, STR(?green_1), 1/0),
    IF(?green_1 = 10, "a", 1/0),
    IF(?green_1 = 11, "b", 1/0),
    IF(?green_1 = 12, "c", 1/0),
    IF(?green_1 = 13, "d", 1/0),
    IF(?green_1 = 14, "e", 1/0),
    IF(?green_1 = 15, "f", 1/0),
    "ERROR"
  ) AS ?green_hex1 )
  BIND (FLOOR(?green - (16 * xsd:integer( ?green / 16 ))) AS ?green_2)
  BIND ( COALESCE(
    IF(?green_2 < 10, STR(?green_2), 1/0),
    IF(?green_2 = 10, "a", 1/0),
    IF(?green_2 = 11, "b", 1/0),
    IF(?green_2 = 12, "c", 1/0),
    IF(?green_2 = 13, "d", 1/0),
    IF(?green_2 = 14, "e", 1/0),
    IF(?green_2 = 15, "f", 1/0),
    "ERROR"
  ) AS ?green_hex2 )
  BIND (CONCAT(STR(?green_hex1), STR(?green_hex2)) AS ?green_hex )
  # blue
  BIND ( FLOOR (?blue / 16) AS ?blue_1 )
  BIND ( COALESCE(
    IF(?blue_1 < 10, STR(?blue_1), 1/0),
    IF(?blue_1 = 10, "a", 1/0),
    IF(?blue_1 = 11, "b", 1/0),
    IF(?blue_1 = 12, "c", 1/0),
    IF(?blue_1 = 13, "d", 1/0),
    IF(?blue_1 = 14, "e", 1/0),
    IF(?blue_1 = 15, "f", 1/0),
    "ERROR"
  ) AS ?blue_hex1 )
  BIND (FLOOR(?blue - (16 * xsd:integer( ?blue / 16 ))) AS ?blue_2)
  BIND ( COALESCE(
    IF(?blue_2 < 10, STR(?blue_2), 1/0),
    IF(?blue_2 = 10, "a", 1/0),
    IF(?blue_2 = 11, "b", 1/0),
    IF(?blue_2 = 12, "c", 1/0),
    IF(?blue_2 = 13, "d", 1/0),
    IF(?blue_2 = 14, "e", 1/0),
    IF(?blue_2 = 15, "f", 1/0),
    "ERROR"
  ) AS ?blue_hex2 )
  BIND (CONCAT(STR(?blue_hex1), STR(?blue_hex2)) AS ?blue_hex )
  BIND (CONCAT(STR(?red_hex), STR(?green_hex), STR(?blue_hex)) AS ?rgb) 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
 }

Query found at

graph TD classDef projected fill:lightgreen; classDef literal fill:orange; classDef iri fill:yellow; v10("?CENTRE") v1("?CENTRELabel") v7("?CENTRE_COORDS") v10("?LIMIT") v26("?b") v29("?blue") v40("?blue_1") v42("?blue_2") v44("?blue_hex") v41("?blue_hex1") v43("?blue_hex2") v10("?data") v12("?description"):::projected v20("?ff") v25("?g") v8("?geoshape"):::projected v28("?green") v35("?green_1") v37("?green_2") v39("?green_hex") v36("?green_hex1") v38("?green_hex2") v18("?hh") v16("?hue") v19("?i") v10("?max_data") v11("?min_data") v21("?p") v14("?percent") v22("?q") v24("?r") v27("?red") v30("?red_1") v32("?red_2") v34("?red_hex") v31("?red_hex1") v33("?red_hex2") v45("?rgb"):::projected v17("?saturation") v13("?spread") v23("?t") v15("?value") v5("?x"):::projected v2("?xLabel"):::projected v9("?x_coords") c12(["bd:serviceParam"]):::iri c14(["#91;AUTO_LANGUAGE#93;,en"]):::literal c2(["wd:Q145"]):::iri f0[["?CENTRELabel = 'en'"]] f0 --> v1 f1[["?xLabel = 'en'"]] f1 --> v2 f2[["?data < ?LIMIT"]] f2 --> v10 f2 --> v10 f3[["?x != 'wd:Q145'?x != 'wd:Q22'?x != 'wd:Q21'?x != 'wd:Q25'?x != 'wd:Q26'"]] f3 --> v5 bind4[/VALUES ?CENTRE/] bind4-->v10 bind40(["wd:Q84"]) bind40 --> bind4 v10 --"wdt:P625"--> v7 bind5[/"'1000^^xsd:integer'"/] bind5 --as--o v10 v5 --"wdt:P3896"--> v8 v5 --"wdt:P17"--> c2 v5 --"wdt:P625"--> v9 bind6[/"http://www.opengis.net/def/function/geosparql/distance(?CENTRE_COORDS,?x_coords)"/] v7 --o bind6 v9 --o bind6 bind6 --as--o v10 f7[["?data < ?LIMIT"]] f7 --> v10 f7 --> v10 f8[["?x != 'wd:Q145'?x != 'wd:Q22'?x != 'wd:Q21'?x != 'wd:Q25'?x != 'wd:Q26'"]] f8 --> v5 bind9[/VALUES ?CENTRE/] bind9-->v10 bind90(["wd:Q84"]) bind90 --> bind9 v10 --"wdt:P625"--> v7 bind10[/"'1000^^xsd:integer'"/] bind10 --as--o v10 v5 --"wdt:P3896"--> v8 v5 --"wdt:P17"--> c2 v5 --"wdt:P625"--> v9 bind11[/"http://www.opengis.net/def/function/geosparql/distance(?CENTRE_COORDS,?x_coords)"/] v7 --o bind11 v9 --o bind11 bind11 --as--o v10 bind14[/"max(?data)"/] v10 --o bind14 bind14 --as--o v10 bind15[/"min(?data)"/] v10 --o bind15 bind15 --as--o v11 v5 --"rdfs:label"--> v2 v10 --"rdfs:label"--> v1 bind16[/"concat('The centre of ',?xLabel,' is about ',str(numeric-round(?data)),' kilometres from the centre of ',?CENTRELabel)"/] v2 --o bind16 v10 --o bind16 v1 --o bind16 bind16 --as--o v12 bind17[/"?max_data - ?min_data"/] v10 --o bind17 v11 --o bind17 bind17 --as--o v13 bind18[/"http://www.w3.org/2001/XMLSchema#integer('100^^xsd:integer' * ?data - ?min_data / ?spread)"/] v10 --o bind18 v11 --o bind18 v13 --o bind18 bind18 --as--o v14 bind19[/"'1^^xsd:integer' - ?percent / '100^^xsd:integer' + '0^^xsd:integer'"/] v14 --o bind19 bind19 --as--o v15 bind20[/"'90^^xsd:integer'"/] bind20 --as--o v16 bind21[/"'1^^xsd:integer'"/] bind21 --as--o v17 bind22[/"?hue / '60^^xsd:integer'"/] v16 --o bind22 bind22 --as--o v18 bind23[/"numeric-floor(?hh)"/] v18 --o bind23 bind23 --as--o v19 bind24[/"?hh - ?i"/] v18 --o bind24 v19 --o bind24 bind24 --as--o v20 bind25[/"?value * '1^^xsd:integer' - ?saturation"/] v15 --o bind25 v17 --o bind25 bind25 --as--o v21 bind26[/"?value * '1^^xsd:integer' - ?saturation * ?ff"/] v15 --o bind26 v17 --o bind26 v20 --o bind26 bind26 --as--o v22 bind27[/"?value * '1^^xsd:integer' - ?saturation * '1^^xsd:integer' - ?ff"/] v15 --o bind27 v17 --o bind27 v20 --o bind27 bind27 --as--o v23 bind28[/"if(?i = '0^^xsd:integer',?value,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '1^^xsd:integer',?q,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '2^^xsd:integer',?p,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '3^^xsd:integer',?p,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '4^^xsd:integer',?t,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '5^^xsd:integer',?value,'1^^xsd:integer' / '0^^xsd:integer')?value"/] v19 --o bind28 v15 --o bind28 v22 --o bind28 v21 --o bind28 v23 --o bind28 bind28 --as--o v24 bind29[/"if(?i = '0^^xsd:integer',?t,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '1^^xsd:integer',?value,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '2^^xsd:integer',?value,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '3^^xsd:integer',?q,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '4^^xsd:integer',?p,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '5^^xsd:integer',?p,'1^^xsd:integer' / '0^^xsd:integer')?p"/] v19 --o bind29 v23 --o bind29 v15 --o bind29 v22 --o bind29 v21 --o bind29 bind29 --as--o v25 bind30[/"if(?i = '0^^xsd:integer',?p,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '1^^xsd:integer',?p,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '2^^xsd:integer',?t,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '3^^xsd:integer',?value,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '4^^xsd:integer',?value,'1^^xsd:integer' / '0^^xsd:integer')if(?i = '5^^xsd:integer',?q,'1^^xsd:integer' / '0^^xsd:integer')?q"/] v19 --o bind30 v21 --o bind30 v23 --o bind30 v15 --o bind30 v22 --o bind30 bind30 --as--o v26 bind31[/"numeric-floor('255^^xsd:integer' * ?r)"/] v24 --o bind31 bind31 --as--o v27 bind32[/"numeric-floor('255^^xsd:integer' * ?g)"/] v25 --o bind32 bind32 --as--o v28 bind33[/"numeric-floor('255^^xsd:integer' * ?b)"/] v26 --o bind33 bind33 --as--o v29 bind34[/"numeric-floor(?red / '16^^xsd:integer')"/] v27 --o bind34 bind34 --as--o v30 bind35[/"if(?red_1 < '10^^xsd:integer',str(?red_1),'1^^xsd:integer' / '0^^xsd:integer')if(?red_1 = '10^^xsd:integer','a','1^^xsd:integer' / '0^^xsd:integer')if(?red_1 = '11^^xsd:integer','b','1^^xsd:integer' / '0^^xsd:integer')if(?red_1 = '12^^xsd:integer','c','1^^xsd:integer' / '0^^xsd:integer')if(?red_1 = '13^^xsd:integer','d','1^^xsd:integer' / '0^^xsd:integer')if(?red_1 = '14^^xsd:integer','e','1^^xsd:integer' / '0^^xsd:integer')if(?red_1 = '15^^xsd:integer','f','1^^xsd:integer' / '0^^xsd:integer')'ERROR'"/] v30 --o bind35 bind35 --as--o v31 bind36[/"numeric-floor(?red - '16^^xsd:integer' * http://www.w3.org/2001/XMLSchema#integer(?red / '16^^xsd:integer'))"/] v27 --o bind36 bind36 --as--o v32 bind37[/"if(?red_2 < '10^^xsd:integer',str(?red_2),'1^^xsd:integer' / '0^^xsd:integer')if(?red_2 = '10^^xsd:integer','a','1^^xsd:integer' / '0^^xsd:integer')if(?red_2 = '11^^xsd:integer','b','1^^xsd:integer' / '0^^xsd:integer')if(?red_2 = '12^^xsd:integer','c','1^^xsd:integer' / '0^^xsd:integer')if(?red_2 = '13^^xsd:integer','d','1^^xsd:integer' / '0^^xsd:integer')if(?red_2 = '14^^xsd:integer','e','1^^xsd:integer' / '0^^xsd:integer')if(?red_2 = '15^^xsd:integer','f','1^^xsd:integer' / '0^^xsd:integer')'ERROR'"/] v32 --o bind37 bind37 --as--o v33 bind38[/"concat(str(?red_hex1),str(?red_hex2))"/] v31 --o bind38 v33 --o bind38 bind38 --as--o v34 bind39[/"numeric-floor(?green / '16^^xsd:integer')"/] v28 --o bind39 bind39 --as--o v35 bind40[/"if(?green_1 < '10^^xsd:integer',str(?green_1),'1^^xsd:integer' / '0^^xsd:integer')if(?green_1 = '10^^xsd:integer','a','1^^xsd:integer' / '0^^xsd:integer')if(?green_1 = '11^^xsd:integer','b','1^^xsd:integer' / '0^^xsd:integer')if(?green_1 = '12^^xsd:integer','c','1^^xsd:integer' / '0^^xsd:integer')if(?green_1 = '13^^xsd:integer','d','1^^xsd:integer' / '0^^xsd:integer')if(?green_1 = '14^^xsd:integer','e','1^^xsd:integer' / '0^^xsd:integer')if(?green_1 = '15^^xsd:integer','f','1^^xsd:integer' / '0^^xsd:integer')'ERROR'"/] v35 --o bind40 bind40 --as--o v36 bind41[/"numeric-floor(?green - '16^^xsd:integer' * http://www.w3.org/2001/XMLSchema#integer(?green / '16^^xsd:integer'))"/] v28 --o bind41 bind41 --as--o v37 bind42[/"if(?green_2 < '10^^xsd:integer',str(?green_2),'1^^xsd:integer' / '0^^xsd:integer')if(?green_2 = '10^^xsd:integer','a','1^^xsd:integer' / '0^^xsd:integer')if(?green_2 = '11^^xsd:integer','b','1^^xsd:integer' / '0^^xsd:integer')if(?green_2 = '12^^xsd:integer','c','1^^xsd:integer' / '0^^xsd:integer')if(?green_2 = '13^^xsd:integer','d','1^^xsd:integer' / '0^^xsd:integer')if(?green_2 = '14^^xsd:integer','e','1^^xsd:integer' / '0^^xsd:integer')if(?green_2 = '15^^xsd:integer','f','1^^xsd:integer' / '0^^xsd:integer')'ERROR'"/] v37 --o bind42 bind42 --as--o v38 bind43[/"concat(str(?green_hex1),str(?green_hex2))"/] v36 --o bind43 v38 --o bind43 bind43 --as--o v39 bind44[/"numeric-floor(?blue / '16^^xsd:integer')"/] v29 --o bind44 bind44 --as--o v40 bind45[/"if(?blue_1 < '10^^xsd:integer',str(?blue_1),'1^^xsd:integer' / '0^^xsd:integer')if(?blue_1 = '10^^xsd:integer','a','1^^xsd:integer' / '0^^xsd:integer')if(?blue_1 = '11^^xsd:integer','b','1^^xsd:integer' / '0^^xsd:integer')if(?blue_1 = '12^^xsd:integer','c','1^^xsd:integer' / '0^^xsd:integer')if(?blue_1 = '13^^xsd:integer','d','1^^xsd:integer' / '0^^xsd:integer')if(?blue_1 = '14^^xsd:integer','e','1^^xsd:integer' / '0^^xsd:integer')if(?blue_1 = '15^^xsd:integer','f','1^^xsd:integer' / '0^^xsd:integer')'ERROR'"/] v40 --o bind45 bind45 --as--o v41 bind46[/"numeric-floor(?blue - '16^^xsd:integer' * http://www.w3.org/2001/XMLSchema#integer(?blue / '16^^xsd:integer'))"/] v29 --o bind46 bind46 --as--o v42 bind47[/"if(?blue_2 < '10^^xsd:integer',str(?blue_2),'1^^xsd:integer' / '0^^xsd:integer')if(?blue_2 = '10^^xsd:integer','a','1^^xsd:integer' / '0^^xsd:integer')if(?blue_2 = '11^^xsd:integer','b','1^^xsd:integer' / '0^^xsd:integer')if(?blue_2 = '12^^xsd:integer','c','1^^xsd:integer' / '0^^xsd:integer')if(?blue_2 = '13^^xsd:integer','d','1^^xsd:integer' / '0^^xsd:integer')if(?blue_2 = '14^^xsd:integer','e','1^^xsd:integer' / '0^^xsd:integer')if(?blue_2 = '15^^xsd:integer','f','1^^xsd:integer' / '0^^xsd:integer')'ERROR'"/] v42 --o bind47 bind47 --as--o v43 bind48[/"concat(str(?blue_hex1),str(?blue_hex2))"/] v41 --o bind48 v43 --o bind48 bind48 --as--o v44 bind49[/"concat(str(?red_hex),str(?green_hex),str(?blue_hex))"/] v34 --o bind49 v39 --o bind49 v44 --o bind49 bind49 --as--o v45 subgraph s1["http://wikiba.se/ontology#label"] style s1 stroke-width:4px; c12 --"wikibase:language"--> c14 end