2

I'm trying to create a model on QGIS 2.18.4 which will allow me to create multiple fixed distance buffers on a selected point(500m, 1km, 2km, 3km,...,50km) with a few clicks, rather than having to do it one by one using the MMQGIS Create Buffer function.

Because I'm working on WGS84, my solution below reprojects the selected point to World Equidistant Conic which uses meters as its distance unit. I then create the buffers, then reproject the created buffers back to WGS84.

Screenshot of my model

My question is, why does my final output appear different from when I create it with MMQGIS? (See screenshot of Singapore below. Purple circle is a 5km buffer I've created using MMQGIS, and the blue circle is what I've created using my model.) I've looked at the MMQGIS python code (see code below) and it appears to apply the same workflow and CRS I've used in my model.

Screenshot of outputs

def mmqgis_buffer_geometry(geometry, meters):
if meters <= 0:
    return None

# To approximate meaningful meter distances independent of the original CRS,
# the geometry is transformed to an azimuthal equidistant projection
# with the center of the polygon as the origin. After buffer creation,
# the buffer is transformed to WGS 84 and returned. While this may introduce
# some deviation from the original CRS, buffering is assumed in practice
# to be a fairly inexact operation that can tolerate such deviation

wgs84 = QgsCoordinateReferenceSystem()
wgs84.createFromProj4("+proj=longlat +datum=WGS84 +no_defs")

latitude = str(geometry.centroid().asPoint().y())
longitude = str(geometry.centroid().asPoint().x())

#proj4 = "+proj=aeqd +lat_0=" + str(geometry.centroid().asPoint().y()) + \
#   " +lon_0=" + str(geometry.centroid().asPoint().x()) + \
#   " +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs"

# For some reason, Azimuthal Equidistant transformation noticed to not be
# working on 10 July 2014. World Equidistant Conic works, but there may be errors.
proj4 = "+proj=eqdc +lat_0=0 +lon_0=0 +lat_1=60 +lat_2=60 " + \
    "+x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"

azimuthal_equidistant = QgsCoordinateReferenceSystem()
azimuthal_equidistant.createFromProj4(proj4)

transform = QgsCoordinateTransform(wgs84, azimuthal_equidistant)
geometry.transform(transform)

newgeometry = geometry.buffer(meters, 7)

wgs84 = QgsCoordinateReferenceSystem()
wgs84.createFromProj4("+proj=longlat +datum=WGS84 +no_defs")

transform = QgsCoordinateTransform(azimuthal_equidistant, wgs84)
newgeometry.transform(transform)

return newgeometry


def mmqgis_buffer_point(point, meters, edges, rotation_degrees):
if (meters <= 0) or (edges < 3):
    return None

# Points are treated separately from other geometries so that discrete
# edges can be supplied for non-circular buffers that are not supported
# by the QgsGeometry.buffer() function

wgs84 = QgsCoordinateReferenceSystem()
wgs84.createFromProj4("+proj=longlat +datum=WGS84 +no_defs")

# print "Point " + unicode(point.x()) + ", " + unicode(point.y()) + " meters " + unicode(meters)

polyline = []
for edge in range(0, edges + 1):
    degrees = ((float(edge) * 360.0 / float(edges)) + rotation_degrees) % 360
    polyline.append(mmqgis_endpoint(point, meters, degrees))

return QgsGeometry.fromPolygon([polyline])

Why is this happening? What can I do to get the same result as when using MMQGIS?

  • In which CRS is your image and which one of the buffers has the correct width? – user30184 Jan 12 '18 at 7:13
  • @user30184 The image is in wgs84. The purple buffer (created with MMQGIS) has the right width. – Park Sang Jin Jan 12 '18 at 7:19
0

I think the difference is that the MMQGIS code takes the shapes centeroid as the origin for reprojection, whereas your model will take the north and south poles. Therefore, you'd only get a truly circular buffer at the equator.

Instead try projecting to SVY21 / Singapore TM EPSG: 3414, a Cartesian coordinate system for Singapore that uses meters as it's units. Then reproject back to WGS84

  • That seems to work, but my next question would be: where in the MMQGIS code does it do what you said it does? It appears that in the past the plugin was reprojecting to Azimuthal Equidistant with the geometry centroid as the origin, but now it appears to be using World Equidistant Conic using the poles. – Park Sang Jin Jan 15 '18 at 1:13
  • I misread the code the first time. There is a separate function for buffering points {mmqgis_buffer_point(point, meters, edges, rotation_degrees)}. This doesn't use any of the re-projection code – firefly-orange Jan 15 '18 at 9:13
  • Ah yes, upon closer inspection, it appears there is another function which uses the Haversine formula to calculate the points along the buffer line, then joins the points together! I should be able to throw something together using this. Thanks! – Park Sang Jin Jan 16 '18 at 3:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.