10.6 Exercises
- Read the script
10-centroid-alg.R
in thecode
folder of the book’s GitHub repo.- Which of the best practices covered in Section 10.2 does it follow?
- Create a version of the script on your computer in an IDE such as RStudio (preferably by typing-out the script line-by-line, in your own coding style and with your own comments, rather than copy-pasting — this will help you learn how to type scripts). Using the example of a square polygon (e.g., created with
poly_mat = cbind(x = c(0, 0, 9, 9, 0), y = c(0, 9, 9, 0, 0))
) execute the script line-by-line. - What changes could be made to the script to make it more reproducible?
- How could the documentation be improved?
- In Section 10.3 we calculated that the area and geographic centroid of the polygon represented by
poly_mat
was 245 and 8.8, 9.2, respectively.- Reproduce the results on your own computer with reference to the script
10-centroid-alg.R
, an implementation of this algorithm (bonus: type out the commands - try to avoid copy-pasting). - Are the results correct? Verify them by converting
poly_mat
into ansfc
object (namedpoly_sfc
) withst_polygon()
(hint: this function takes objects of classlist()
) and then usingst_area()
andst_centroid()
.
- Reproduce the results on your own computer with reference to the script
- It was stated that the algorithm we created only works for convex hulls. Define convex hulls (see Chapter 5) and test the algorithm on a polygon that is not a convex hull.
- Bonus 1: Think about why the method only works for convex hulls and note changes that would need to be made to the algorithm to make it work for other types of polygon.
- Bonus 2: Building on the contents of
10-centroid-alg.R
, write an algorithm only using base R functions that can find the total length of linestrings represented in matrix form.
- In Section 10.4 we created different versions of the
polycentroid()
function that generated outputs of classsfg
(poly_centroid_sfg()
) and type-stablematrix
outputs (poly_centroid_type_stable()
). Further extend the function by creating a version (e.g., calledpoly_centroid_sf()
) that is type stable (only accepts inputs of classsf
) _and returnssf
objects (hint: you may need to convert the objectx
into a matrix with the commandsf::st_coordinates(x)
).- Verify it works by running
poly_centroid_sf(sf::st_sf(sf::st_sfc(poly_sfc)))
- What error message do you get when you try to run
poly_centroid_sf(poly_mat)
?
- Verify it works by running
References
Abelson, Harold, Gerald Jay Sussman, and Julie Sussman. 1996. Structure and Interpretation of Computer Programs. Second. The MIT Electrical Engineering and Computer Science Series. Cambridge, Massachusetts: MIT Press.
Wise, Stephen. 2001. GIS Basics. CRC Press.
Xiao, Ningchuan. 2016. GIS Algorithms: Theory and Applications for Geographic Information Science & Technology. London. https://doi.org/10.4135/9781473921498.
Bellos, Alex. 2011. Alex’s Adventures in Numberland. London: Bloomsbury Paperbacks.
Berg, Mark de, Otfried Cheong, Marc van Kreveld, and Mark Overmars. 2008. Computational Geometry: Algorithms and Applications. Springer Science & Business Media.
O’Rourke, Joseph. 1998. Computational Geometry in C. Second. Cambridge, UK, ; New York, NY, USA: Cambridge University Press.
Kaiser, M.J., and T.L. Morin. 1993. “Algorithms for Computing Centroids.” Computers & Operations Research 20 (2): 151–65. https://doi.org/10.1016/0305-0548(93)90071-P90071-P).
Knuth, Donald E. 1974. “Computer Programming as an Art.” Commun. ACM 17 (12): 667–73. https://doi.org/10.1145/361604.361612.
This chapter does not teach programming itself.For more on programming, we recommend Wickham (2014a), Gillespie and Lovelace (2016), and Xiao (2016). ↩
Lines of code that do not contain valid R should be commented out, by adding a
#
to the start of the line, to prevent errors.See line 1 of the10-hello.R
script.↩Prior steps can be referred to with a comment or with an if statement such as
if(!exists("x")) source("x.R")
(which would run the script filex.R
if the objectx
is missing).↩This example shows that
source()
works with URLs (a shortened version is used here), assuming you have an internet connection.If you do not, the same script can be called withsource("code/10-centroid-alg.R")
, assuming you are running R from the root directory of thegeocompr
folder, which can be downloaded from https://github.com/Robinlovelace/geocompr.↩The result can be verified with the following formula (which assumes a horizontal base):area is half of the base width times height, (A = B H / 2).In this case (10 10 / 2 = 50).↩
See
?lapply
for documentation and Chapter 13 for more on iteration.↩The CGAL function
CGAL::centroid()
is in fact composed of 7 sub-functions as described at https://doc.cgal.org/latest/Kernel_23/groupcentroidgrp.html allowing it to work on a wide range of input data types, whereas the solution we created works only on a very specific input data type.The source code underlying GEOS functionCentroid::getCentroid()
can be found at https://github.com/libgeos/geos/search?q=getCentroid.↩You can also explicitly set the output of a function by adding
return(output)
into the body of the function, whereoutput
is the result to be returned.↩Note that the functions we created are called iteratively in
lapply()
andvapply()
function calls.↩