Get a centroid in QGIS via python - python

I am trying to get a centroid of a polygon in QGIS using python. Here is my code
layerPluto = iface.addVectorLayer("/path/to/mn_mappluto_16v1/MNMapPLUTO.shp", "PLUTO", "ogr")
features = layerPluto.getFeatures()
counter = 0
for feature in features:
# Get the first feature from the layer
if counter < 3:
print feature['Address']
print getCentroid(feature)
counter += 1
... which gives me a "name 'getCentroid' is not defined" error.
I find this surprising, since the QGIS python editor has getCentroid as a dropdown syntax-completion option.
I also tried using this function as a method of the feature object via feature.getCentroid() and received a similar error ("'QgsFeature' object has no attribute 'getCentroid'").
Similarly, trying centroid(feature) gives me the error "NameError: name 'centroid' is not defined," while feature.centroid() gives me "'QgsFeature' object has no attribute 'centroid'".
Is there another method I should be using for this operation?

centroid() is a method of QgsGeometry class.
You can retrieve the geometry section of a QgsFeature with geometry() method
and so you can obtain centroid geometry siply chaining the two methods:
feature.geometry().centroid()

Related

Loading a Mesh in OpenCV Python with viz module

I am creating an AR-app, where you can virtually try on shoes. For now I have the location of the foot calculated using SolvePnp. Now I want to render the 3D object (.obj) file on top of the image, using the OpenCv Viz module. (Manually compiling worked)
I want to load the object as an cv::viz::Mesh object using the cv::viz::Mesh::load function, but I don't find the corresponding Python function call.
I tried
mesh = cv2.viz_Mesh()
mesh.load('shoe.obj', cv2.viz_Mesh_LOAD_OBJ)
and also
mesh = cv2.viz_Mesh_load('shoe.obj', cv2.viz_Mesh_LOAD_OBJ)
I always get the error:
AttributeError: 'cv2.viz_Mesh' object has no attribute 'load'
Using the dir() function from python I found all other methods except the load method, which is a static method (that's probably why it isn't here).
>>> dir(cv2) #contains the Viz Classes
['', ... , 'viz',... ,'viz_Mesh]
>>> dir(cv2.viz) #Stuff like Enums , Colors etc
['',...'Color_amethyst', ..., 'MOUSE_EVENT_MOUSE_DBL_CLICK'...]
>>> dir(cv2.viz_Mesh) #pyhton functions and other non static methods
['__class__', ... , 'colors','polygons']
Does someone know what the correct python call is?
Appendix: the cv2.viz_Mesh_LOAD_OBJ and cv2.viz_MESH_LOAD_OBJ represent only integers 2 ( = enums), thus
>>>print(cv2.viz_MESH_LOAD_OBJ)
>>>print(cv2.viz_Mesh_LOAD_OBJ)
2
2
I found the solution. I overlooked some methods in the dir(cv2.viz).
The correct python call would be
mesh = cv2.viz.readMesh('./shoe.ply')
It only accepts the path to .ply file, but not to .obj files (Version 4.5.5). Maybe other formats will be added in newer versions

Pass Python object as argument to function in "parfeval"

I am trying to pass one Python object as an argument to a function that I am evaluating in the background with parfeval. The Python object is an instance of a Python class, and I detail it below. However, to reproduce the error, I will exemplify with a Python dictionary... However, simply using struct(pydict) would not work because I would lose all the attributes and methods in the Python class.
Assume the Python dictionary is
o = py.dict(pyargs('soup',3.57,'bread',2.29,'bacon',3.91,'salad',5.00));
and the function is
function t = testFunc(x)
t = x{'soup'};
end
If I evaluate the function, I get the correct answer:
>> testFunc(o)
ans =
3.5700
However, if I use parfeval, I get the following error:
>> f = parfeval(#testFunc,1,o);
>> fetchOutputs(f)
Error using parallel.Future/fetchOutputs
One or more futures resulted in an error.
Caused by:
Error using testFunc (line 2)
Invalid or deleted object.
Is there a workaround to this error that doesn't mean I have to recode my whole Python class?
Here is the preview of the object I want to pass as a function to parfeval:
clt =
Python Client with properties:
enforce_enums: 1
api_key: [1×45 py.str]
request_number: [1×1 py.int]
logger: [1×1 py.logging.Logger]
session: [1×1 py.authlib.integrations.httpx_client.oauth2_client.OAuth2Client]
token_metadata: [1×1 py.tda.auth.TokenMetadata]
<tda.client.synchronous.Client object at 0x000001ECA08EAE50>
I didn't find any restrictions in the documentation that says that parfeval function inputs cannot be anything...
https://www.mathworks.com/help/matlab/ref/parfeval.html
"X1,...,Xm — Input arguments
comma-separated list of variables or expressions... Input arguments, specified as a comma-separated list of variables or expressions"
One of the limitations of the MATLAB->Python support is that Python objects cannot be serialized. parfeval (and other parallel constructs) require serialization to transfer data from one MATLAB process to another.
You might be able to work around this by having each worker build the data structure directly and storing it / accessing it via parallel.pool.Constant, like this:
oC = parallel.pool.Constant(#() py.dict(pyargs('soup',3.57,'bread',2.29,'bacon',3.91,'salad',5.00)));
fetchOutputs(parfeval(#(c) c.Value{'salad'}, 1, oC))

Cannot use Kmeans Cluster inside a python function

As above - I'm trying to create a function for clustering specific data types and displaying them.
The function looks a bit like this at the moment,
def cluster(inputData):
variable_s= inputData.groupby(['x','z', 'c'])['w'].sum().unstack()
## 4 Clusters
model = cluster.MiniBatchKMeans(n_clusters=5)
model.fit(variable_s.fillna(0))
variable_s['kmeans_4'] = model.predict(variable_s.fillna(0))
## 8 Clusters
model = cluster.KMeans(n_clusters=8)
model.fit(variable_s.fillna(0))
variable_s['kmeans_8'] = model.predict(variable_s.fillna(0))
## Looking at hourly distribution.
variable_s_Hourly = variable_s.reset_index(1, inplace=True)
variable_s_Hourly['hour'] = variable_s_Hourly.index.hour
return variable_s, variable_s_Hourly
it uses
from sklearn import cluster
to do the clustering, and it's giving me an error like this,
AttributeError: 'function' object has no attribute 'MiniBatchKMeans'
Any clues on solving this issue? I would have thought the function would be fine as long as the library is imported into the file itself - this is in jupyter notebook :)
Cheers!
The function name ("cluster") shadows the import. Change the function name to solve it.
Alternatively, you can give the import an alias:
from sklearn import cluster as clstr

I am running the code below in python and getting the error 'AttributeError: 'QgridWidget' object has no attribute 'to_excel''

I am trying to use to excel function using the code below. I am getting the error df.to_excel('dataset1.xlsx')
Below is the code.
df=qgrid.show_grid(data)
df.to_excel('dataset1.xlsx')
qgrid.show_grid() returns a QgridWidget instance. You can access the underlying dataframe using the df attribute:
grid = qgrid.show_grid(data)
grid.df.to_excel('dataset1.xlsx')

AttributeError: 'ParentedTree' object has no attribute 'label'

I am basically working on parsed tree and trying to annotate tree nodes dominating empty categories(Empty node annotation).
I have defined a recurvsive function as below but the error that I am getting is "AttributeError: 'ParentedTree' object has no attribute 'label'".
def annotateTraceNodes(node):
numChildren = len(node);
numNone=0;
for child in node:
if isinstance(child,Tree):
annotateTraceNodes(child);
if(numChildren==0 or child.label().endswith("-NONE-")):
numNone+=1;
if(numChildren==numNone):
print "setting the label";
node.set_label(node.label()+"-NONE-");
Google suggests you're using NLTK, which I'm going to assume is the case.
A ParentedTree does not have a method called .label(). So when you write things like this:
child.label().endswith("-NONE-")
Python doesn't know what to do.
A Tree, on the other hand, does have a .label() method. Did you perhaps use a ParentedTree instead of a Tree somewhere?
Could also be a versioning issue.
Worked for me with version 3.3
pip install nltk==3.3

Categories