PREFIX ex: PREFIX wgs: PREFIX geo: PREFIX rdfs: PREFIX iter: PREFIX fun: PREFIX xsd: PREFIX rdf: GENERATE { ?{fun:bnode("here")} wgs:lat ?latitude; wgs:long ?longitude; rdfs:label ?display_name; ex:address [ a ex:Address; ex:city_district ?city_district; ex:city ?city; ex:state ?state; ex:postcode ?postcode; ex:country ?country; ex:country_code ?country_code ]; ex:boundingbox [ geo:hasGeometry ?box ] . GENERATE { ?{fun:bnode("here")} geo:coordinates ?{fun:bnode("l0")} . ?rest rdf:first [ a geo:Coordinate; wgs:lat ?lat; wgs:long ?long ]; rdf:rest ?tail . } ITERATOR iter:JSONElement(?source,"$.geojson.coordinates.*.*") AS ?coord WHERE { BIND(fun:JSONPath(?coord,"$.hasNext") AS ?hasNext) BIND(fun:JSONPath(?coord,"$.position") AS ?pos) BIND(xsd:decimal(fun:JSONPath(?coord,"$.element[0]")) AS ?long) BIND(xsd:decimal(fun:JSONPath(?coord,"$.element[1]")) AS ?lat) BIND(fun:bnode("l{STR(?pos)}") AS ?rest) BIND(IF(?hasNext,fun:bnode("l{STR(?pos+1)}"),rdf:nil) AS ?tail) }. } SOURCE AS ?source WHERE { BIND(STRDT(fun:JSONPath(?source,"$.lat"),xsd:decimal) AS ?latitude) BIND(STRDT(fun:JSONPath(?source,"$.lon"),xsd:decimal) AS ?longitude) BIND(fun:JSONPath(?source,"$.display_name") AS ?display_name) BIND(fun:JSONPath(?source,"$.address.city_district") AS ?city_district) BIND(fun:JSONPath(?source,"$.address.city") AS ?city) BIND(fun:JSONPath(?source,"$.address.state") AS ?state) BIND(fun:JSONPath(?source,"$.address.country") AS ?country) BIND(fun:JSONPath(?source,"$.address.country_code") AS ?country_code) BIND(fun:JSONPath(?source,"$.address.postcode") AS ?postcode) BIND(fun:JSONPath(?source,"$.boundingbox[0]") AS ?lat1) BIND(fun:JSONPath(?source,"$.boundingbox[1]") AS ?lat2) BIND(fun:JSONPath(?source,"$.boundingbox[2]") AS ?long1) BIND(fun:JSONPath(?source,"$.boundingbox[3]") AS ?long2) BIND("POLYGON(({?long1} {?lat1}, {?long1} {?lat2}, {?long2} {?lat2}, {?long2} {?lat1}, {?long1} {?lat1}))"^^geo:wktLiteral AS ?box) }