Skip to content

Commit

Permalink
adds option for polygons and other geotries,
Browse files Browse the repository at this point in the history
uses centroids for non point inputs,
adds user agent
allows non 4326 geometries as input
  • Loading branch information
riccardoklinger committed Dec 14, 2020
1 parent 7870589 commit 2d388a3
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 26 deletions.
4 changes: 3 additions & 1 deletion GetMapCoordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ def clicked(self, pt, b):
url = "https://api.placekey.io/v1/placekey"
headers = {
'apikey': key,
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'user-agent': 'placekey-qgis/1.0 singleMode'
}
payload = {
"query": {
Expand All @@ -69,6 +70,7 @@ def clicked(self, pt, b):
headers=headers,
data=json.dumps(payload)
)
print(response.text)
self.dockwidget.lineEdit_2.setText(str(response.json()["placekey"]))
self.dockwidget.toolButton.setChecked(False)
self.iface.mapCanvas().setCursor(Qt.ArrowCursor)
Expand Down
7 changes: 4 additions & 3 deletions metadata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
name=Placekey Connector
qgisMinimumVersion=3.0
description=adds placekeys to your data
version=0.9.2
version=1.0
author=Riccardo Klinger
email=riccardo.klinger@gmail.com

Expand All @@ -20,7 +20,8 @@ repository=https://github.com/riccardoklinger/placekey

hasProcessingProvider=yes
# Uncomment the following line and add your changelog:
changelog=2020/12/06 V0.9.2 solves description and feedback for manage keys processing
changelog= 2020/12/13 V1.0 Adds support for Polygon/Line geomtries and non 4326 layers.
2020/12/06 V0.9.2 solves description and feedback for manage keys processing
2020/12/05 V0.9.1 small bugs in metadata and removal of unused data
2020/12/05 V0.9 initial release

Expand All @@ -31,7 +32,7 @@ homepage=https://github.com/riccardoklinger/placekey
#category=Web
icon=icon.png
# experimental flag
experimental=True
experimental=False

# deprecated flag (applies to the whole plugin, not just a single version)
deprecated=False
Expand Down
86 changes: 65 additions & 21 deletions placekeyAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import time
from PyQt5.QtCore import (QCoreApplication, QUrl, QVariant)
from qgis.core import (Qgis,
QgsCoordinateTransform,
QgsFeature,
QgsFeatureSink,
QgsFields,
Expand Down Expand Up @@ -64,6 +65,7 @@ def __init__(self):
PostalField = 'Postal Code Field'
CountryField = 'ISO Country Code Field'
copyAttributes = 'Copy Attributes'
DropGeo = 'Use Attributes only'

def createInstance(self):
return type(self)()
Expand Down Expand Up @@ -113,14 +115,23 @@ def shortHelpString(self):
return self.tr(
"""This algorithm adds a placekey to your table. The placekey is
defined either by a set of:
- (lat, lon) / taken from the geometry
- (lat, lon) taken from the geometry
- (street_address, city, region, country) or
- (street_address, region, postal_code, country)
and a placename if needed.
The street_address should contain both the street name as well as
the house number.
If no lat/lon and no country is available we will default to US.
<a href="https://docs.placekey.io/">Documentation</a>
<a href="https://docs.placekey.io/">Placekey API Documentation</a>
______________
Parameters:
- Location Name Field: the name of the place / "Twin Peaks Petroleum"
- City Name Field: The city where the place is located / "San Francisco"
- Address Field: The street address of the place / "1543 Mission Street"
- Region Name Field: The second-level administrative region below nation for the place. In the US, this is the state / "California" or "CA"
- Postal Code: The postal code for the place / "94105"
- Country Code: The ISO 2-letter Country Code for the place. Defaults to 'US' if none given.
- Copy all Attributes: If checked we will copy all attributes from the input layer to the output. If false, we will only copy the feature id.
- Use Attributes Only: If checked we will not use lat/lon as input atributes which then will
The output layer will be stored in EPSG 4326.
Make sure to have your placekey API key added to the options using 'Manage placekey API keys"
""")

Expand Down Expand Up @@ -196,13 +207,19 @@ def initAlgorithm(self, config=None):
self.addParameter(
QgsProcessingParameterBoolean(
self.copyAttributes,
self.tr('Copy all attributes')
self.tr('Copy all Attributes')
)
)
self.addParameter(
QgsProcessingParameterBoolean(
self.DropGeo,
self.tr('Use Attributes Only')
)
)
self.addParameter(
QgsProcessingParameterFeatureSink(
self.OUTPUT,
self.tr('Layer with placekeys')
self.tr('Layer with Placekeys')
)
)

Expand All @@ -221,7 +238,7 @@ def valueCheck(self, string):
else:
return string

def addPayloadItem(self, parameters, context, feature, feedback):
def addPayloadItem(self, parameters, source, context, feature, feedback):
"""getting field names"""
locationName = self.parameterAsString(
parameters,
Expand Down Expand Up @@ -253,6 +270,11 @@ def addPayloadItem(self, parameters, context, feature, feedback):
self.CountryField,
context
)
geometry = self.parameterAsString(
parameters,
self.DropGeo,
context
)
item = {
"query_id": str(feature.id()),
}
Expand All @@ -271,22 +293,26 @@ def addPayloadItem(self, parameters, context, feature, feedback):
item["iso_country_code"] = self.valueCheck(str(feature[country]))
if country == "":
item["iso_country_code"] = "US"
try:
featGeometry = feature.geometry()
if geometry == "false":
featGeometry = feature.geometry().centroid()
sourceCrs = source.sourceCrs()
if source.sourceCrs != QgsCoordinateReferenceSystem(4326):
destCrs = QgsCoordinateReferenceSystem(4326)
tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
featGeometry.transform(tr)
if math.isnan(featGeometry.asPoint().y()) is False:
item["latitude"] = featGeometry.asPoint().y()
item["longitude"] = featGeometry.asPoint().x()
else:
print("strange geometry")
except BaseException:
test = 1
print("strange geometry found at feature with id " + str(feature.id()))
return item

def getKeys(self, payload, result, key, feedback):
url = "https://api.placekey.io/v1/placekeys"
headers = {
'apikey': key,
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'user-agent': 'placekey-qgis/1.0 batchMode'
}
response = requests.request(
"POST",
Expand Down Expand Up @@ -382,6 +408,11 @@ def inputCheck(self, source, parameters, context, feedback):
self.CountryField,
context
)
geometry = self.parameterAsString(
parameters,
self.DropGeo,
context
)
# no attributes given:
if source.wkbType() in [0, 3, 4, 100]:
feedback.pushInfo(
Expand All @@ -392,12 +423,13 @@ def inputCheck(self, source, parameters, context, feedback):
addressName == "" and
regionName == "" and
zipCode == "" and
country == ""):
country == "" and geometry == "true"):
raise QgsProcessingException(
"""Invalid set of inputs! Either provide a layer with
geometry or proper attribute definitions!"""
"""You disabled geometry. Please provide additional
information like city name, zipcode and address /
housenumber to conszruct the WHERE part."""
)
if cityName == "" and zipCode == "":
if cityName == "" and zipCode == "" and geometry == "true":
raise QgsProcessingException(
"please provide either city name or postal code"
)
Expand Down Expand Up @@ -431,6 +463,11 @@ def processAlgorithm(self, parameters, context, feedback):
self.copyAttributes,
context
)
geometry = self.parameterAsString(
parameters,
self.DropGeo,
context
)
fields = source.fields()
if copy == "false":
fields.clear()
Expand All @@ -443,7 +480,7 @@ def processAlgorithm(self, parameters, context, feedback):
context,
fields,
QgsWkbTypes.Point,
QgsCoordinateReferenceSystem(4326)
source.sourceCrs()
)
if sink is None:
raise QgsProcessingException(
Expand All @@ -463,12 +500,12 @@ def processAlgorithm(self, parameters, context, feedback):
if feedback.isCanceled():
break
payload["queries"].append(self.addPayloadItem(parameters,
source,
context,
feature,
feedback))
batches.append(payload)
result = self.getKeys(batches[0], result, key, feedback)
print(result)
else:
"""batch mode"""
index = 0
Expand All @@ -478,12 +515,14 @@ def processAlgorithm(self, parameters, context, feedback):
index += 1
if index % 100 != 0 and index != source.featureCount():
payloadItem = self.addPayloadItem(parameters,
source,
context,
feature,
feedback)
payload["queries"].append(payloadItem)
if index % 100 == 0:
payloadItem = self.addPayloadItem(parameters,
source,
context,
feature,
feedback)
Expand All @@ -492,6 +531,7 @@ def processAlgorithm(self, parameters, context, feedback):
payload = {"queries": []}
if index == source.featureCount():
payloadItem = self.addPayloadItem(parameters,
source,
context,
feature,
feedback)
Expand All @@ -509,6 +549,10 @@ def processAlgorithm(self, parameters, context, feedback):
'''processing result'''
features = source.getFeatures()
feedback.pushInfo('merging source with placekeys...')
if geometry == "true":
feedback.pushInfo('attributes used for inputs, resulting geometry is the centroid of input geometries')
if geometry == "false":
feedback.pushInfo('centroids of geometries used for inputs and resulting geomtry of placekey layer')
for current, feature in enumerate(features):
if feedback.isCanceled():
break
Expand All @@ -517,7 +561,7 @@ def processAlgorithm(self, parameters, context, feedback):
if copy == "true":
attributes = feature.attributes()
try:
fet.setGeometry(feature.geometry())
fet.setGeometry(feature.geometry().centroid())
except BaseException:
feedback.pushInfo('no geometry available')
for index in range(0, len(result)):
Expand Down
7 changes: 6 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ Please get yourself a placekey API key at <a href="https://www.placekey.io/">pla

## Usage

Currently point layers and delimited data files (example a csv) are supported. PostgreSQL data layers should work as well. If no Latitude and Longitude is available in your layer, make sure to fill the attributes:
Currently vector layers and delimited data files (example a csv) are supported. PostgreSQL data layers should work as well. If no Latitude and Longitude is available in your layer, make sure to fill the attributes:
- placename
- street name + house number
- postcode
- city
- region
- country (only US and NL are supported right now). If no country is provided, the plugin defaults it to "US".
If you would like to drop the geomery information check "use Attributes Only" in the dialog.

If you want to have all source attributes of the input dataset copied to the output, make sure to enable "Copy All Atributes".

Resulting Layer will use EPSG 4326 and the centroids of input data if available.

## Support
If you find issues, have enhancement wishes, make sure to create an issue on this repo and we will get back to you as soon as possible. If it's an option on your side, please make sure to add some minimal data example for your issue / user story

0 comments on commit 2d388a3

Please sign in to comment.