﻿{"id":3325,"date":"2016-06-17T10:41:15","date_gmt":"2016-06-17T09:41:15","guid":{"rendered":"http:\/\/www.sigterritoires.fr\/?p=3325"},"modified":"2019-04-07T11:03:49","modified_gmt":"2019-04-07T09:03:49","slug":"developper-une-application-avec-pgrouting-sous-windows-5ecrire-un-wrapper","status":"publish","type":"post","link":"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-5ecrire-un-wrapper\/","title":{"rendered":"D\u00e9velopper une application avec pgrouting sous Windows (5):\u00e9crire un Wrapper"},"content":{"rendered":"<p>Un wrapper est une fonction de PostgreSQL comme une autre, qui contient des fonctionnalit\u00e9s de <a href=\"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-1\/\">pgRouting<\/a> et <a href=\"https:\/\/www.sigterritoires.fr\/index.php\/debuter-avec-postgrespostgis\/\">PostGIS<\/a> sous une forme plus facile \u00e0 utiliser que lors de l&rsquo;appel des fonctions pgRouting et PostGIS directement.<br \/>\nLes fonctions natives de pgRouting ont \u00e9t\u00e9 con\u00e7ues pour \u00eatre g\u00e9n\u00e9riques afin de pouvoir \u00eatre utilis\u00e9es dans le plus large \u00e9ventail d&rsquo;applications. Bien que cela offre de la flexibilit\u00e9, l&rsquo;inconv\u00e9nient est que vous pouvez \u00eatre oblig\u00e9s de remodeler temporairement votre propre structure de donn\u00e9es avant de pouvoir appliquer des fonctions de pgRouting.<br \/>\nR\u00e9diger une fonction wrapper adapt\u00e9e \u00e0 votre structure de donn\u00e9es diminue la n\u00e9cessit\u00e9 de passer par des requ\u00eates SQL encombrantes.<br \/>\nUne autre raison d&rsquo;utiliser les fonctions de wrapper est de contourner les attaques par injection SQL. \u00c9riger une barri\u00e8re fonctionnelle entre les entr\u00e9es de l&rsquo;utilisateur et les fonctions de pgRouting natives vous permet de d\u00e9sinfecter les entr\u00e9es utilisateur.<!--more--><\/p>\n<p>PostgreSQL supporte de nombreux langages de programmation pour l&rsquo;\u00e9criture des fonctions utilisateur, mais SQL et PL\/pgSQL sont les plus courantes. Nous allons voir ici un exemple avec PL\/pgSQL.<\/p>\n<p>Jusqu&rsquo;\u00e0 pr\u00e9sent, dans notre s\u00e9rie d&rsquo;articles, nous nous sommes cantonn\u00e9s au niveau des donn\u00e9es du r\u00e9seau, mais le but est d&rsquo;arriver \u00e0 mettre en place une application web de recherche d&rsquo;itin\u00e9raire. Dans ce cas, l&rsquo;id\u00e9e est de pr\u00e9senter une carte \u00e0 l&rsquo;utilisateur, et lui permettre de d\u00e9finir un point de d\u00e9part et un point d&rsquo;arriv\u00e9e. Parmi les multiples possibilit\u00e9s, retenons la plus simple: un clic sur la carte pour d\u00e9finir le point de d\u00e9part et un autre clic pour d\u00e9finir le point d&rsquo;arriv\u00e9e.<\/p>\n<p>Notre page web envoie alors deux couples de coordonn\u00e9es x-y et s&rsquo;attend \u00e0 recevoir en retour l&rsquo;itin\u00e9raire conseill\u00e9 pour relier ces deux points g\u00e9ographiques.<\/p>\n<p>Si vous avez suivi la s\u00e9rie d&rsquo;articles, vous pouvez mesurer la distance qu&rsquo;il y a entre ce que la page web fait et les recherches d&rsquo;itin\u00e9raire que nous avons vu, o\u00f9 on doit rentrer comme param\u00e8tres les identifiant des n\u0153uds de d\u00e9part et d&rsquo;arriv\u00e9e, ainsi que d&rsquo;autres param\u00e8tres selon l&rsquo;algorithme utilis\u00e9.<\/p>\n<p>N&rsquo;oublions pas que, entre notre page web et notre base Postgresql\/Postgis nous aurons aussi <a href=\"https:\/\/www.sigterritoires.fr\/index.php\/debuter-avec-geoserver\/\">Geoserver<\/a>. Une possibilit\u00e9 est d&rsquo;\u00e9crire une requ\u00eate complexe dans Geoserver, mais nous avons une solution beaucoup plus simple et efficace en utilisant un wrapper dans PostgreSQL.<\/p>\n<p>Ce wrapper, qui n&rsquo;est autre chose qu&rsquo;une nouvelle fonction que nous allons ajouter dans notre base Postgres, s&rsquo;occupera de traduire les x-y transmis par la page web en param\u00e8tres utilisables par notre algorithme de recherche d&rsquo;itin\u00e9raire, d&rsquo;optimiser son ex\u00e9cution , et de mettre en forme le r\u00e9sultat pour l&rsquo;affichage sur la page web.<\/p>\n<p>Le code pr\u00e9sent\u00e9 ici est une variation d&rsquo;un exemple que l&rsquo;on trouve dans diff\u00e9rents sites traitant de pgrouting et que l&rsquo;on retrouve sous le nom de pgr_fromAtoB.<\/p>\n<div class='stb-container stb-style-grey stb-caption-box stb-collapsed'><div class='stb-caption'><div class='stb-logo'><img class='stb-logo__image' src='data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN\/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz\/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH\/w\/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA\/g88wAAKCRFRHgg\/P9eM4Ors7ONo62Dl8t6r8G\/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt\/qIl7gRoXgugdfeLZrIPQLUAoOnaV\/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl\/AV\/1s+X48\/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H\/LcL\/\/wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93\/+8\/\/UegJQCAZkmScQAAXkQkLlTKsz\/HCAAARKCBKrBBG\/TBGCzABhzBBdzBC\/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD\/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q\/pH5Z\/YkGWcNMw09DpFGgsV\/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY\/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4\/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L\/1U\/W36p\/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N\/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26\/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE\/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV\/MN8C3yLfLT8Nvnl+F30N\/I\/9k\/3r\/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt\/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi\/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a\/zYnKOZarnivN7cyzytuQN5zvn\/\/tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO\/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3\/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA\/0HIw6217nU1R3SPVRSj9Yr60cOxx++\/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3\/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX\/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8\/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb\/1tWeOT3dvfN6b\/fF9\/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR\/cGhYPP\/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF\/6i\/suuFxYvfvjV69fO0ZjRoZfyl5O\/bXyl\/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o\/2j5sfVT0Kf7kxmTk\/8EA5jz\/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5\/wAAgOkAAHUwAADqYAAAOpgAABdvkl\/FRgAAD41JREFUeNrsmnl0lOW9xz\/v7PtkliyTsGUhCQQCYYeyirSCQLXttcqil0Vse9uqrUvrbattbW0PiqJXa61el1YxgAQwyL6VsoNECCQhCZDNTJaZzL69M\/PeP3y5h+PBXhW8vbfH55znvGeemXne+fyW7+95f2cESZL4ZxgK\/knGlyBfgnxBQ\/UF7VsEdKTT6SJBEHoFQUjI657\/DyDmi5dafgRS385de++fNuUrm8+erZ8\/Zsyov3m9Xkem09ngcDr2BALBgqws52pAB8Su182F6yC\/pprTp3\/f3Ng0aP++A3MGDMyXIuGokF9YQDwWIycvL+X3BZTZ2Zm9CiktWSzmjvyCgVU+X6B\/YeHAe2RjJv6hIKFQeO65s+e+s\/LJlTfPmT2PaDxBVnYOfr+PPl+QRCJGPJ5Ar9OTYbOT5XCQm+tKxuMxlV6vae7fz7XZHwhYSkuLl\/8jQUZ977v3rJ8yeXp+SckQjEYT1du2sXXbNto6LhGPiYhikqQoggAqpRKLyUL5iArKR4ykfPhwFKkkOoO2tbAwf6NGo2nOzXM9+78K0tPTM2rXju3vlpUNy7U7MjFbLPz0kX9n647tpFJpJCkNgoSYEEmnkhj0OhSCmmAkQiwWJRGLkV9QyDe\/8S8MGzoEn7eP6TdMXV9UVPB7hULZrlQq3F84SDqdymptaVv\/7DNPTvnxgz9Do9bw\/Xvv5YPaWswmLXa7NTG4sKDLbLH0JGIJw\/nGhkKrxay227MIRyJEY3Eam5tparqI3+tl+owZLF6wmNxcl7\/X06uaN2\/OIovFvPELV63TZ84sX1+5dsqDD\/+CdEri17\/5LfVNzZgtZkaWFX\/44osvrlAqVUdEUSxubWl9UqczDjYZTUiSRDQWw9PrpbHpPLv37Gb3vv3s3bcfr7eP5ctWWAf2zwt4vd4pkUjYmpOT8wbwqa2sfOyxxz41RDyeKO5o63whO9tptmU4OHzkCG9WVuJwOhEEBV6fT9u\/X257hjXDf+TI0WddOf3GGY1mRTKZxBsI0enuJRSJoNeZGD6sjLy8bDo6P+TMB7U0NNYxduxYbWND48SsbKc3MzNz0xdW2S9cbLn\/pZf\/4BJQYndksmffLvRGAyqVCo1Gg88f1CxYtOCnt337G\/vycvNG6fUGkkkRUUzT0tZJd4+HhJgkGk8SCMYpKx3Bwtu\/TX5RPs2NTfzljdfIsNno6faMOHz46F+ArOseWqlUqvBcXf0tixbcSU52Nm3trTRdbMFkMiKlIZWCpJgi4AvisDsU2c4skmIcjVbP7j3bePrZ58jOyycz00lZ8WAqKsaQFkUmjJvK8ePHiEYi7Nm3h4qKUeTlDRhdVlZqBITr7pG2jo6bPjj9Qc7ad9agUqvx+XzEE3EEQYkkSUhpiMViJOJxcrJyUalVKFQCCgW8+ZfXudDSiccT4N3N1Ty16nf4A30YrCY0OgPjxkzEYjWhN1jYsXMbDruNaDSeffTo8WcB0\/X0iMrfF5jUPzePebNnk5mZRafbjUIAQSFASgLSRGMRADq73CTTKVRKJQqFwMD8fC51RQiFgqSTUTrcLdSe+YDCgiIS8RhFg0tw2DIRRRXnztXR6+lFTCZtFqsxA0heT484W1taJ7jdnaxc+ThebzdanfojCCn9kSxLEkkxDgg0NJynt7sLpaAmEU9y95Kl5Pd30flhK73uFjRaDWNHlWOz6LCa9dhtGahVSsxmI6m0RG3tafr160c8lhze0f7hPdcTJJnhsHk6uzpYtmwFWdnZ6LQaVIKSdDqFSq1AEATUKj2g5NKlVjZVV6NQgiSkGFxcxDNP\/oof\/XAp96y4m41VVUz6ykQQUlgsZjyeXmJiEqvVisFo5Oy5WkDByZPHXIJCSFy30EqlUoOamy4O7td\/EFUbNxKJhJg8ZTpWix53dwAJAa1Wj9Vmo8vdSUJMsHbd24wcWcHkyZMQRZGsrGwe\/PEDKBQK4vE4wUAQjVqHUqXkfOPZVCAQUmbYtOj1JoLBEJIEw4aNTIVD4RGAEkhds0eUSuXZcWPH\/K21tQWEFOPGTUSlUrPgjjv8v3z0kRdvmDrxeP3ZU9hsNrJy8jCYbPT2eHj66VX87cAhdFoDWq2BcFQkFImTTEoYDBY0ai3Hjx+JLF++\/Adr33rjtwohHQsFAygEBVarhTO1NcqOjjbtpymMVy2IS5cuZdOmTbjdblwuFxaLxVJz+uwDrS0tmf0HFrC28k1cLhdTpswQzWbjz5PJ5DMKIT2zob7RlZXtQhCU6HQGxJRIY3MrcVHC6bSj0elQqjQk4klaLl1kzbq32L17Z9+ihYv\/LSsrq9rn7Z3x3pZ3C4oGD+bmOXMxGSwMKsg\/63DYN\/5PMFcNrVdfffW\/r3a7nSVLlvjv\/eG9j4uJG\/\/wu5WPW8qHDqV8+Ggi4ZjZ6\/U99Oqrr952yy3z92zfsXNUliuXDJsZ0GBz2EhKCt7btosT79dgt1mJRHx0d3bQ0tKMu8vDwoUL2gA\/4NAbtAJAefkI1BoN+\/66Xcqw3xopLi6UrjnZvV6v4qmnnko1NjdLoXDYnD9gACNGjeeRnz9Ebe0pXK7cr82adeN9wWC4efLkie0N9TVYrVa0GgXRSIRkWkJr0BEKh9m\/fx9r1qxhc3U1Le1dFBSWMHPGjJcWLFggtrW1ZdTU1BQLCpg2dRqRSJRRoyYIQ4YMOQmkrxVEAagB038891yzIImrFyxcFnr5T88TDoYoKhpCJBwR5tx888MnTpwY1uXu3VReVho4feoYCgH0GjXBPg+tF5poOl9Pb68Hvc5CYWEZZUMrWLHsrrdWrXrqtcrKSpqaGsfs2LE1d\/r06YwePY6mpjpOnDjYrdVq669Vfi9DGICcqqoNqdoztWjVamNpSSmjxkzkwYfu5ZX\/fIlMZ47x0Ucfvdtut48Mh2J1Y0ePjNTVngJBIiMjA6vVit1up7CwkGHDhzMov4D+\/ftJSqXicFXVxuTiRYuNZ07X3BMORxQ\/e+Qx2lsv0d7ayl13LX3fZDLtvxYQQc4fA5AJ5ANjqrdUZ2zduunct761KHb69Cnq6mqZMnkmx44dJRqLaFavfuYr48ePHxgOR\/uGDy9NxWIhVGolao0arVaLRqNBrVYjSWm6unuEAwePrFi+fNmSwYMLHliz5s3pLzz\/MsXFJQgKgeam+qDT6Xj+mh6sBEFQyhBOGWI4MBQYNHr06PynnnyucNfu9wSVSiOEYzGOHNzLE088ydAhQ5FIc\/z4cfHd6o3K+vPNCrXWhFqtQ6VUkpY+slA6nUZMpgj6+zDopHROVqZi8Z1LmDZ1Jlu2VPHWmrd55unVb+bmuX4it5CinxdEA2QAA2SI8cAwoJ\/D4cwoKxuqmzBhkmL02Anq1c8+QUX5GObe\/HWqt2zk\/vvvp7CwCL\/Px\/unTnHw8EHON17C7\/cTi4lIpFGpFBh0BnJzMpkwYSJfnXUTKpWCw0cOY9QbOHTkIIvvXHpBCTqjyXhOpVa8otfr1\/+9c9cngehlb5QAY4FJQKkcZlpAePjhR1RlQ4fRfKFeyB9UpHi78s8gwMqVq9hctYGly+4mx+UCSSIhinR3d9Pr8YCURq\/Xk5Odg0ajRW\/Qs3\/vXwkEg2g0Wpqampnz9VtJJuL0eXqw2Wz4fQFyc7NX5+blPPRJrSPV38kRJaABjPLUXfH55B\/\/+ELM6XRITzyx0pKIx0GAufO+wWuvv8HBA3u4Y+EiHnzgPubPv4Wc3DxUKgWlJcX4fD60Gi0XLjZjMBh55eU\/MXvOPGprz9LS2szkyTORxASP\/vwntHcHGTBgILOmTyEQCN5rNptOmi2mP38WEEnWblHuBsZlS4jyesTn8\/nj8Xhq184dYiQa0d1513fMubku1le+yew589my9T2qNlUxdfoNvPDi84yqGMOAgQPYsX0by5av4DdPPM4PvvdDztU30NPrp7GxnnDEz7y5t9LefomLbV0MGFhES0szle908v17vktHh3txqaWo8mpe+STVSskAfUAn8CHQLVfgMBACuqLRaP0fX3rx2M6dO9q8np5I1Ttr49+6bQE3zZ7L\/r17WLrsu7S3t3O+oR5Xbj\/+\/MbrWK0OqjZsYHDhMN6urGJ4xUTKyysoKhyM05mFRqPBZDQzftw4vN4uxESchrozSKkU4XCkNJ1OOz9LjlyWXgdQAFQA5UAhYJdDzy8DBgCzIJBjMpmzf\/mrX7sOHTyouvHGWerSoWW8V72JcRMmEQr4aGg4z5AhQ+jp8TBowMDGi23tme7uroza0x+QYbFis5mZecNsCgryCQT9vLulmvqGOirKK5g7Zz42u2VvcUnhTVfzyCeBXFkML0vwEDnhB8mAannDgOwlCTCo1epsURT7z50339rW1qooKS4RSkqHcOr9k9K0adOFAwf2x\/r1G9BqNOrfKy4tvWPL1h3ZN06bQXNzI8FgiJk3zGLM2JGo1RqcTqfcvJCoqzuHz+ePzPrqjFt1Ou2OT5sjaVnqokCvHGohoEf2Qj7gAqwylEPOI1EUxSQgVr+7OQmoas+cEVKplABIe\/fukcLhMIDC4XCMvvOuJYq5X5vDiZOH8AdCGIxmotEQsWgIf1CBLTObFCkaG+s4deoUI0aMqNPptBc\/6xElLVs8LANcAE4Ce4Ed8vV94JIMefkU4JD3FQExlUqJslHS4XA4LRtvUCgUGltUmG91u1tpbr7E6Iqx5Lhy6PZ4qGtoI9M1kD5fmAMHDrF7zy5UKjXFJUUHN2x4p\/Gz5MjHYZXyD9AAesAsF8xsefaXPXTZO0a5+6GVp0reQ7isiEajUX377bdb9AaDsrioFHOGkcOHDmPQm5l38zzCsQDZmS6OHz+Gw5GJ290ZjEZD3\/nFo794SxTFz\/Wom5ZvnpItG5e95JHDTC9DWWQhyLgCVCuvq+SckmQ1TITD4axXXnllwn333ZdfPrKMynXr6OkL8M0pM9i4uZJeTy\/\/etcyTtW8z6KFd7KhqvL0unXrW+S9kp+3HSRdMa8Eisoe65Etrr5iauT3tJefRuXvxuVrARDzeDymdWvXOg1anbDg27fR7e6gpqaG225bxNGjx5g0cSrPrF4V3bRpY6fsUeHzhtYnVX6u2Fj42NrfM8TlG2YAo4GvARNXrVo1PJVMalrb2jSTJk0Rurs7EUWJ7du2uHfu2nkI2AjsAtzSVX705wX5JLArX0tXgfl47hlkOS\/Nzc0d0eV2Z40dNz6voCA\/c\/v27b12uz3a2Nh4GtgHnAO8H7XQJL4okGsZSvkclyELhEnOsdgV8t9zZRH8vwpytZIgXCUU+cwgX\/7z4UuQL0H++UD+awDc\/MMFLMO8WgAAAABJRU5ErkJggg==' alt='img'\/><\/div><div class='stb-caption-content'>Texte du wrapper<\/div><div class='stb-tool'><\/div><\/div><div class='stb-content'>\n<p>&#8211;DROP FUNCTION pgr_route_entreAetB(varchar, double precision, double precision,<br \/>\n&#8212; double precision, double precision);<\/p>\n<p>CREATE OR REPLACE FUNCTION pgr_route_entreAetB(<br \/>\nIN tbl varchar,<br \/>\nIN x1 double precision,<br \/>\nIN y1 double precision,<br \/>\nIN x2 double precision,<br \/>\nIN y2 double precision,<br \/>\nOUT seq integer,<br \/>\nOUT gid integer,<br \/>\nOUT direction double precision,<br \/>\nOUT cost double precision,<br \/>\nOUT geom geometry)<\/p>\n<p>RETURNS SETOF record AS<\/p>\n<p>$BODY$<br \/>\nDECLARE<br \/>\nsql text;<br \/>\nrec record;<br \/>\nsource integer;<br \/>\ntarget integer;<br \/>\npoint integer;<br \/>\nbuff double precision;<br \/>\ndist double precision;<br \/>\nlegid integer;<\/p>\n<p>BEGIN<\/p>\n<p>&#8212; Trouver le n\u0153ud le plus proche des lat\/lon en entr\u00e9e<\/p>\n<p>EXECUTE &lsquo;SELECT id::integer, the_geom::geometry FROM &lsquo; || tbl || &lsquo;_vertices_pgr<br \/>\nORDER BY the_geom &lt;-&gt;ST_GeometryFromText(\u00a0\u00bbPOINT(&lsquo;<br \/>\n|| x1 || &lsquo; &lsquo; || y1 || &lsquo;)\u00a0\u00bb,4326) LIMIT 1&rsquo; INTO rec;<br \/>\nsource := rec.id;<\/p>\n<p>EXECUTE &lsquo;SELECT id::integer, the_geom::geometry FROM &lsquo; || tbl || &lsquo;_vertices_pgr<br \/>\nORDER BY the_geom &lt;-&gt;ST_GeometryFromText(\u00a0\u00bbPOINT(&lsquo;<br \/>\n|| x2 || &lsquo; &lsquo; || y2 || &lsquo;)\u00a0\u00bb,4326) LIMIT 1&rsquo; INTO rec;<br \/>\ntarget := rec.id;<\/p>\n<p>&#8211;D\u00e9finir une sous-zone de travail<br \/>\nEXECUTE &lsquo;SELECT ST_Distance(ST_GeomFromText(\u00a0\u00bbPOINT(&lsquo; || x1 ||&rsquo; &lsquo; || y1 ||&rsquo;)\u00a0\u00bb,4326),&rsquo;<br \/>\n&lsquo;ST_GeomFromText(\u00a0\u00bbPOINT(&lsquo; || x2 ||&rsquo; &lsquo; || y2 ||&rsquo;)\u00a0\u00bb,4326)) as dist&rsquo; INTO rec;<br \/>\nbuff := GREATEST(rec.dist,0.5);<\/p>\n<p>&#8211;Trouver l&rsquo;identifiant du tron\u00e7on de d\u00e9part<br \/>\nEXECUTE &lsquo;SELECT gid as legid FROM &lsquo; || tbl || &lsquo; WHERE source = &lsquo; || source || &lsquo; LIMIT 1&rsquo; INTO rec;<br \/>\nlegid := rec.legid;<\/p>\n<p>&#8212; Calculer l&rsquo;itin\u00e9raire avec l&rsquo;algorithme A*<\/p>\n<p>seq := 0;<br \/>\nsql := &lsquo;SELECT gid, the_geom,pgr_astar.cost, source, target, ST_Reverse(the_geom) AS flip_geom<br \/>\nFROM &lsquo;<br \/>\n&lsquo;pgr_astar(\u00a0\u00bbSELECT gid as id, source::int, target::int, &lsquo;<br \/>\n&lsquo;length_m * &lsquo; || tbl || &lsquo;.cost as cost, x1, y1, x2, y2 FROM &lsquo;<br \/>\n|| quote_ident(tbl) ||<br \/>\n&lsquo; WHERE the_geom @ (SELECT ST_buffer(the_geom,&rsquo;<br \/>\n|| buff || &lsquo;) FROM &lsquo;<br \/>\n|| quote_ident(tbl) || &lsquo; WHERE gid=&rsquo; || legid || &lsquo;)&rsquo;<br \/>\n\u00a0\u00bb&rsquo;, &lsquo;<br \/>\n|| source || &lsquo;, &lsquo; || target<br \/>\n|| &lsquo; , false, false), &lsquo;<br \/>\n|| quote_ident(tbl) || &lsquo; WHERE id2 = gid ORDER BY seq&rsquo;;<\/p>\n<p>&#8212; m\u00e9moriser la point de d\u00e9part<\/p>\n<p>point := source;<\/p>\n<p>FOR rec IN EXECUTE sql<br \/>\nLOOP<\/p>\n<p>&#8212; Inverser les tron\u00e7ons si n\u00e9cessaire<\/p>\n<p>IF ( point != rec.source ) THEN<br \/>\nrec.the_geom := rec.flip_geom;<br \/>\npoint := rec.source;<br \/>\nELSE<br \/>\npoint := rec.target;<br \/>\nEND IF;<\/p>\n<p>&#8212; Calculer le cap<\/p>\n<p>EXECUTE &lsquo;SELECT degrees( ST_Azimuth(<br \/>\nST_StartPoint(\u00a0\u00bb&rsquo; || rec.the_geom::text ||&rsquo; \u00a0\u00bb),<br \/>\nST_EndPoint(\u00a0\u00bb&rsquo; || rec.the_geom::text || &lsquo; \u00a0\u00bb) ) )&rsquo;<br \/>\nINTO direction;<\/p>\n<p>&#8212; Return<\/p>\n<p>seq := seq + 1;<br \/>\ngid := rec.gid;<br \/>\ncost := rec.cost;<br \/>\ngeom := rec.the_geom;<br \/>\nRETURN NEXT;<\/p>\n<p>END LOOP;<br \/>\nRETURN;<br \/>\nEND;<br \/>\n$BODY$<br \/>\nLANGUAGE &lsquo;plpgsql&rsquo; VOLATILE STRICT;<\/p>\n<p><\/div><\/div><br \/>\nVoyons maintenant qu&rsquo;est-ce que cette fonction fait.<\/p>\n<h2>Param\u00e9trage de la fonction<\/h2>\n<p>Tout d&rsquo;abord nous avons le param\u00e9trage de la fonction:<br \/>\n<em>CREATE OR REPLACE FUNCTION pgr_route_entreAetB(<\/em><br \/>\n<em> IN tbl varchar,<\/em><br \/>\n<em> IN x1 double precision,<\/em><br \/>\n<em> IN y1 double precision,<\/em><br \/>\n<em> IN x2 double precision,<\/em><br \/>\n<em> IN y2 double precision,<\/em><br \/>\n<em> OUT seq integer,<\/em><br \/>\n<em> OUT gid integer,<\/em><br \/>\n<em> OUT direction double precision,<\/em><br \/>\n<em> OUT cost double precision,<\/em><br \/>\n<em> OUT geom geometry)<\/em><\/p>\n<p>Nous d\u00e9finissons 5 param\u00e8tres en entr\u00e9e: la table contenant le r\u00e9seau et les coordonn\u00e9es du point de d\u00e9part et d&rsquo;arriv\u00e9e.<br \/>\nNous d\u00e9finissons aussi les param\u00e8tres en sortie : une s\u00e9rie de tron\u00e7ons comportant un num\u00e9ro d&rsquo;ordre (seq), l&rsquo;identifiant du tron\u00e7on (gid), la direction g\u00e9ographique ou cap de ce tron\u00e7on (direction), le co\u00fbt associ\u00e9 au tron\u00e7on et la g\u00e9om\u00e9trie de celui-ci pour pouvoir le dessiner sur la carte r\u00e9sultat.<\/p>\n<h2>Pr\u00e9-traitement des param\u00e8tres<\/h2>\n<p>Ensuite, nous devons pr\u00e9parer les param\u00e8tres de notre algorithme. Ici nous allons utiliser l&rsquo;algorithme <a href=\"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-2lalgorithme-a-star\/\">a-star<\/a> de pgrouting.<\/p>\n<p><em>EXECUTE &lsquo;SELECT id::integer, the_geom::geometry FROM &lsquo; || tbl ||&rsquo;_vertices_pgr<\/em><br \/>\n<em> ORDER BY the_geom ST_GeometryFromText(\u00a0\u00bbPOINT(&lsquo;<\/em><br \/>\n<em> || x1 || &lsquo; &lsquo; || y1 || &lsquo;)\u00a0\u00bb,4326) LIMIT 1&rsquo; INTO rec;<\/em><br \/>\n<em> source := rec.id;<\/em><\/p>\n<p><em>EXECUTE &lsquo;SELECT id::integer, the_geom::geometry FROM &lsquo; || tbl || &lsquo;_vertices_pgr<\/em><br \/>\n<em> ORDER BY the_geom ST_GeometryFromText(\u00a0\u00bbPOINT(&lsquo;<\/em><br \/>\n<em> || x2 || &lsquo; &lsquo; || y2 || &lsquo;)\u00a0\u00bb,4326) LIMIT 1&rsquo; INTO rec;<\/em><br \/>\n<em> target := rec.id;<\/em><\/p>\n<p>Ces deux paragraphes recherchent les identifiants des deux points de la table de n\u0153uds de notre r\u00e9seau les plus proches des coordonn\u00e9es en entr\u00e9e.<br \/>\nLes valeurs entre || sont remplac\u00e9es lors de l&rsquo;ex\u00e9cution par les param\u00e8tres en entr\u00e9e de la fonction.<\/p>\n<p><em>&#8211;D\u00e9finir une sous-zone de travail<\/em><br \/>\n<em> EXECUTE &lsquo;SELECT ST_Distance(ST_GeomFromText(\u00a0\u00bbPOINT(&lsquo; || x1 ||&rsquo; &lsquo; || y1 ||&rsquo;)\u00a0\u00bb,4326),&rsquo;<\/em><br \/>\n<em> &lsquo;ST_GeomFromText(\u00a0\u00bbPOINT(&lsquo; || x2 ||&rsquo; &lsquo; || y2 ||&rsquo;)\u00a0\u00bb,4326)) as dist&rsquo; INTO rec;<\/em><br \/>\n<em> buff := GREATEST(rec.dist,0.5);<\/em><\/p>\n<p>Pour optimiser la recherche d&rsquo;itin\u00e9raires, il est fortement recommand\u00e9 de limiter a recherche \u00e0 une sous-zone (bbox) de notre r\u00e9seau. Ce paragraphe calcule la distance entre le point de d\u00e9part et d&rsquo;arriv\u00e9e et d\u00e9finit une zone de recherche une fois et demie plus grande que cette distance. Les tron\u00e7ons situ\u00e9s en dehors de cette zone ne seront pas pris en compte pour la recherche d&rsquo;itin\u00e9raires possibles.\u00a0 Ici nous avons utilis\u00e9 la fonction GREATEST qui permet de d\u00e9finir une sous-zone minimale : si la distance \u00e0 vol d&rsquo;oiseau est inf\u00e9rieure \u00e0 0,5\u00b0 on prend par d\u00e9faut 0,5\u00b0 comme sous-zone. On aurait pu d\u00e9finir un facteur comme:<\/p>\n<p><em>buff :=rec.dist * 1.5<br \/>\n<\/em><\/p>\n<p>Il est clair que ce facteur (1.5) doit \u00eatre d\u00e9cid\u00e9 en connaissance de cause, si non il peut amener la fonction \u00e0 ne pas trouver de solution. Par exemple, si vous avez deux vall\u00e9es s\u00e9par\u00e9es par une montagne sans routes qui la traversent, la distance calcul\u00e9e ici \u00e9tant \u00e0 vol d&rsquo;oiseau, elle peut ne pas inclure le col le plus proche.<\/p>\n<p><em>&#8211;Trouver l&rsquo;identifiant du tron\u00e7on de d\u00e9part<\/em><br \/>\n<em> EXECUTE &lsquo;SELECT gid as legid FROM &lsquo; || tbl || &lsquo; WHERE source = &lsquo; || source || &lsquo; LIMIT 1&rsquo; INTO rec;<\/em><br \/>\n<em> legid := rec.legid;<\/em><\/p>\n<p>Pour exclure les tron\u00e7ons trop \u00e9loign\u00e9s nous allons utiliser la fonction <em><strong>ST_buffer<\/strong><\/em> appliqu\u00e9e \u00e0 partir du tron\u00e7on de d\u00e9part. Ils nous faut alors trouver l&rsquo;identifiant de ce tron\u00e7on, car pour l&rsquo;instant nous n&rsquo;avons que les identifiants de la table des n\u0153uds.<\/p>\n<p>Nous pouvons maintenant ex\u00e9cuter l&rsquo;algorithme :<\/p>\n<p><em>sql := &lsquo;SELECT gid, the_geom,pgr_astar.cost, source, target, ST_Reverse(the_geom) AS flip_geom<\/em><br \/>\n<em> FROM &lsquo;<\/em><br \/>\n<em> &lsquo;pgr_astar(\u00a0\u00bbSELECT gid as id, source::int, target::int, &lsquo;<\/em><br \/>\n<em> &lsquo;length_m * &lsquo; || tbl || &lsquo;.cost as cost, x1, y1, x2, y2 FROM &lsquo;<\/em><br \/>\n<em> || quote_ident(tbl) ||<\/em><br \/>\n<em> &lsquo; WHERE the_geom @ (SELECT ST_buffer(the_geom,&rsquo;<\/em><br \/>\n<em> || buff || &lsquo;) FROM &lsquo;<\/em><br \/>\n<em> || quote_ident(tbl) || &lsquo; WHERE gid=&rsquo; || legid || &lsquo;)&rsquo;<\/em><br \/>\n<em> \u00a0\u00bb&rsquo;, &lsquo;<\/em><br \/>\n<em> || source || &lsquo;, &lsquo; || target<\/em><br \/>\n<em> || &lsquo; , false, false), &lsquo;<\/em><br \/>\n<em> || quote_ident(tbl) || &lsquo; WHERE id2 = gid ORDER BY seq&rsquo;;<\/em><\/p>\n<p>Le co\u00fbt utilis\u00e9 ici est la longueur en m\u00e8tres du tron\u00e7on multipli\u00e9 par la colonne \u00ab\u00a0cost\u00a0\u00bb de la table. La fonction ST_buffer limite le nombre de tron\u00e7ons de la recherche \u00e0 ceux situ\u00e9s dans la zone d\u00e9finie lors de la g\u00e9n\u00e9ration de la variable <em><strong>buff<\/strong><\/em>.<\/p>\n<p>La suite, inverser le tron\u00e7on et calculer le cap vont ensemble. Ils sont ici pour montrer un exemple de calcul non pr\u00e9vu dans l&rsquo;algorithme et comment l&rsquo;int\u00e9grer dans le wrapper. Si vous n&rsquo;en voyez pas l&rsquo;utilit\u00e9, les effacer du wrapper n&rsquo;aura aucun effet sur l&rsquo;itin\u00e9raire r\u00e9sultant. L&rsquo;inversion du tron\u00e7on est n\u00e9cessaire pour calculer la v\u00e9ritable direction dans le cas o\u00f9 le tron\u00e7on est emprunt\u00e9 en sens inverse (du point target vers le point source). Ceci explique la partie \u00ab\u00a0S<em>T_Reverse(the_geom) AS flip_geom<\/em>\u00a0\u00bb dans la clause SELECT.<\/p>\n<h2>Ajout du wrapper \u00e0 la base postgres<\/h2>\n<p>Pour pouvoir int\u00e9grer cette nouvelle fonction dans votre base PostgreSQL, simplement copiez le texte du wrapper dans une fen\u00eatre SQL et ex\u00e9cutez la requ\u00eate:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3332\" data-permalink=\"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-5ecrire-un-wrapper\/w1\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?fit=1489%2C600&amp;ssl=1\" data-orig-size=\"1489,600\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"w1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?fit=640%2C258&amp;ssl=1\" class=\"aligncenter size-large wp-image-3332\" src=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1-1024x413.png?resize=640%2C258\" alt=\"ajout du wrapper parmi les fonctions de postgres\" width=\"640\" height=\"258\" srcset=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?resize=1024%2C413&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?resize=300%2C121&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?resize=768%2C309&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?resize=1200%2C484&amp;ssl=1 1200w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?w=1489&amp;ssl=1 1489w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w1.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a>La nouvelle fonction est maintenant dans la liste des fonctions de votre base.<\/p>\n<p>Nous pouvons maintenant la tester avec QGis en utilisant la fen\u00eatre de gestion de base de donn\u00e9es.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3336\" data-permalink=\"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-5ecrire-un-wrapper\/w2\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png?fit=1210%2C638&amp;ssl=1\" data-orig-size=\"1210,638\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"w2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png?fit=640%2C338&amp;ssl=1\" class=\"aligncenter size-large wp-image-3336\" src=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2-1024x540.png?resize=640%2C338\" alt=\"w2\" width=\"640\" height=\"338\" srcset=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png?resize=1024%2C540&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png?resize=300%2C158&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png?resize=768%2C405&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png?resize=1200%2C633&amp;ssl=1 1200w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w2.png?w=1210&amp;ssl=1 1210w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a>Nous rentrons le nom de la table contenant notre r\u00e9seau, et les coordonn\u00e9es des points de d\u00e9part et d&rsquo;arriv\u00e9e.<\/p>\n<p>Une fois ex\u00e9cut\u00e9e, la requ\u00eate renvoie la liste des tron\u00e7ons de l&rsquo;itin\u00e9raire. En cliquant sur le bouton \u00ab\u00a0<strong>Charger<\/strong>\u00a0\u00bb nous pouvons voir l&rsquo;affichage de l&rsquo;itin\u00e9raire (sur fond d&rsquo;OpensStreetMap):<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3337\" data-permalink=\"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-5ecrire-un-wrapper\/w3\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?fit=1795%2C1049&amp;ssl=1\" data-orig-size=\"1795,1049\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"w3\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?fit=640%2C374&amp;ssl=1\" class=\"aligncenter size-large wp-image-3337\" src=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3-1024x598.png?resize=640%2C374\" alt=\"itin\u00e9raire dans qgis\" width=\"640\" height=\"374\" srcset=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?resize=1024%2C598&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?resize=300%2C175&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?resize=768%2C449&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?resize=1200%2C701&amp;ssl=1 1200w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?w=1795&amp;ssl=1 1795w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w3.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a>Nous pouvons aussi tester une requ\u00eate un peu plus complexe, pour n&rsquo;obtenir qu&rsquo;une seule entit\u00e9 en r\u00e9sultat:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3338\" data-permalink=\"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-5ecrire-un-wrapper\/w4\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png?fit=1215%2C641&amp;ssl=1\" data-orig-size=\"1215,641\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"w4\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png?fit=640%2C338&amp;ssl=1\" class=\"aligncenter size-large wp-image-3338\" src=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4-1024x540.png?resize=640%2C338\" alt=\"w4\" width=\"640\" height=\"338\" srcset=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png?resize=1024%2C540&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png?resize=300%2C158&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png?resize=768%2C405&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png?resize=1200%2C633&amp;ssl=1 1200w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w4.png?w=1215&amp;ssl=1 1215w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p><em>SELECT ST_MakeLine(route.geom) FROM ( SELECT geom FROM pgr_route_entreAetB(&lsquo;ways&rsquo;,-4.4888433,48.3967909,-4.5267335, 48.403296) ORDER BY seq) AS route<\/em><\/p>\n<p>Cette requ\u00eate prend la liste des tron\u00e7ons r\u00e9sultant de la fonction pgr_route_entreAetB et fabrique une seule entit\u00e9 MultiLigne. Remarquez le nom de la colonne g\u00e9om\u00e9trie g\u00e9n\u00e9r\u00e9e.<\/p>\n<p>Si nous chargeons cette entit\u00e9 dans QGis nous remarquerons que visuellement le r\u00e9sultat est identique. Par contre la quantit\u00e9 d&rsquo;information retourn\u00e9 est optimis\u00e9e.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3339\" data-permalink=\"https:\/\/www.sigterritoires.fr\/index.php\/developper-une-application-avec-pgrouting-sous-windows-5ecrire-un-wrapper\/w5\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?fit=1801%2C1041&amp;ssl=1\" data-orig-size=\"1801,1041\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"w5\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?fit=640%2C370&amp;ssl=1\" class=\"aligncenter size-large wp-image-3339\" src=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5-1024x592.png?resize=640%2C370\" alt=\"r\u00e9sultat avec st_makeline\" width=\"640\" height=\"370\" srcset=\"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?resize=1024%2C592&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?resize=300%2C173&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?resize=768%2C444&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?resize=1200%2C694&amp;ssl=1 1200w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?w=1801&amp;ssl=1 1801w, https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2016\/06\/w5.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a>Nous garderons cette derni\u00e8re requ\u00eate pour l&rsquo;utiliser lors de la mise en place de Geoserver, ce que nous ferons dans le prochain article.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un wrapper est une fonction de PostgreSQL comme une autre, qui contient des fonctionnalit\u00e9s de pgRouting et PostGIS sous une forme plus facile \u00e0 utiliser que lors de l&rsquo;appel des fonctions pgRouting et PostGIS directement. Les&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"give_campaign_id":0,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sfsi_plus_gutenberg_text_before_share":"","sfsi_plus_gutenberg_show_text_before_share":"","sfsi_plus_gutenberg_icon_type":"","sfsi_plus_gutenberg_icon_alignemt":"","sfsi_plus_gutenburg_max_per_row":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[311,62],"tags":[336,326,227,312,58,335],"class_list":["post-3325","post","type-post","status-publish","format-standard","hentry","category-postgresql","category-qgis-2","tag-fonction","tag-pgrouting","tag-postgis","tag-postgresql","tag-qgis","tag-wrapper"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p6XU0A-RD","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/posts\/3325","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/comments?post=3325"}],"version-history":[{"count":0,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/posts\/3325\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/media?parent=3325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/categories?post=3325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/tags?post=3325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}