banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

#1 Wed 13 January 2010 15:11

Tony VINCENT
Participant actif
Lieu: Poitiers
Date d'inscription: 13 Jan 2010
Messages: 86

Problème de projection avec OpenLayers - Google Maps - GeoJSON

Bonjour,


Je suis un petit nouveau sur ce forum, et j'ai besoin d'un petit peu d'aide.
Avant de poster, j'ai essayé de trouver une réponse à mon problème, mais rien y fait. Je n'ai pas trouvé, ou pas testé comme il fallait.

Je vous expose mon problème, je souhaite utiliser OpenLayers, l'API Google Maps et une base de données Postgres/Postgis  pour faire une petite application de Webmapping.


Je fais une requête avec ST_ASGEOJSON sur ma base Postgres pour afficher une nouvelle couche, mais lorsque je l'affiche avec le fond carte google,
elle est toute applatie.

La donnée dans la base est en projection 27582.

Voici une partie du code que j'utilise (il y a un peu de code PHP) et en pièce jointe l'aperçu du résultat.

Je suis preneur, pour les remarques et commentaires, concernant mon problème.

Cordialement,

Tony



/********************************************************
** Code utilisé
*********************************************************/
var map;
var lon = -0.4;
var lat = 46.139343;
var zoom = 8;

function init() {

var options = {
        projection: "EPSG:4326",                // Definit le type de projection
    //maxExtent: new OpenLayers.Bounds(295000, 2000000, 520000, 2250000), //Poitou-Charentes
        'numZoomLevels': 10                    // Definit le nombre de fois que l'on peut zoomer ou dezoomer
    };

    ////
        map = new OpenLayers.Map('map', options);

    ////       
    gphy = new OpenLayers.Layer.Google(
                "Google Physical",
                {type: G_PHYSICAL_MAP}
            );

        map.addLayer(gphy);


<?php

//// Boucle pour construitre l'ensemble des layers,
// en fonction de la variable "$layer_config"
for ($j=0;$j<sizeof($layer_config_1);$j++)
{

    //// Requête SQL
    $query_1 = 'SELECT ST_ASGEOJSON(ST_Transform(the_geom, 4326),5) FROM '.$bd_schema_1.'.'.$layer_config_1[$j]['bd_table'].' WHERE numreg = \'54\' ';

    //// Décommenter pour test
    //echo $query_1;

    //// Afficher un message d'erreur, s'il y a une erreur dans la connexion ou la requête SQL
    $result_1 = pg_query($dbconn, $query_1);
    if (!$result_1) {
        echo 'Une erreur s\'est produite '.$layer_config_1[$j]['lib_etendu'].'.';
        exit;
    }

////
$i = 1;

//// Construction du layer
echo 'var featurecollection = {
"type": "FeatureCollection",
              "features": [
                {"geometry": {
                    "type": "GeometryCollection",
                    "geometries": [
';

//// Boucle qui va recupérer les valeurs des enregistrements
while ($row_1 = pg_fetch_assoc($result_1))
{
    //// On affiche le résultat de l'enregistrement
    print_r( $row_1['st_asgeojson']);

    //// Ajouter une virgule après chaque enregistrement, sauf pour le dernier
    if ($i < pg_num_rows($result_1))
    {
        echo ',';
    }
   
    //// On incrémente $i
    $i++;
}

////
echo '                   ]
                },
                "type": "Feature",
                "properties": {"ID": "'.$j.'"}}
              ]
           };

';

////
echo 'var geojson_format = new OpenLayers.Format.GeoJSON();
    var '.$layer_config_1[$j]['lib'].' = new OpenLayers.Layer.Vector("'.$layer_config_1[$j]['lib_etendu'].'");
    map.addLayer('.$layer_config_1[$j]['lib'].');
    '.$layer_config_1[$j]['lib'].'.addFeatures(geojson_format.read(featurecollection));

';
}

?>

/////////////////////////////////////////////////////////////////////////////////////
//// Options de présentation de la carte
/////////////////////////////////////////////////////////////////////////////////////

    //// Permet de changer le fond de carte
        map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':true}));
    //// Affichage de la barre de zoom
    map.addControl(new OpenLayers.Control.PanZoomBar());
    //// Lien permettant de réinitialiser la carte
    map.addControl(new OpenLayers.Control.Permalink());
    //// Affichage de la bar d'échelle
    map.addControl(new OpenLayers.Control.ScaleLine());
    //// Affichage d'imagette de positionnement
    map.addControl(new OpenLayers.Control.OverviewMap());
    ////
    //map.addControl(new OpenLayers.Control.KeyboardDefaults());
    //// Positionnement de la souris
    map.addControl(new OpenLayers.Control.MousePosition());


    //// Recentrage de la carte sur le Poitou-Charentes
        map.setCenter(new OpenLayers.LonLat(lon,lat), zoom);


//// Fin options de présentation
/////////////////////////////////////////////////////////////////////////////////////


        }



/*************************************************************
*
*************************************************************/

Hors ligne

 

#2 Wed 13 January 2010 15:24

Yves
Membre du bureau
Lieu: Aix-les-Bains
Date d'inscription: 22 Mar 2006
Messages: 9864
Site web

Re: Problème de projection avec OpenLayers - Google Maps - GeoJSON

Bonjour,
Regarde sur doc.openlayers.org, section : "Spérical Mercator" wink

Il faut utiliser proj4js pour reprojeter à la volé tes données, et définir ta carte comme étant une projection sphéricalMercator.

Y.


Yves Jacolin, bénévole de l'association GeoRezo.net, agit au nom et pour le compte de l'association - Partageons ce qui nous départage !!  - GeoRezo vous aide ? Aidez GeoRezo !

Hors ligne

 

#3 Wed 13 January 2010 15:30

Jeirhome
Membre
Lieu: Liverion
Date d'inscription: 22 Aug 2006
Messages: 4298
Site web

Re: Problème de projection avec OpenLayers - Google Maps - GeoJSON

Bonjour,

Pour le code, tu peux utiliser la balise CODE, ça rend le message un peu plus lisible.

Peux-tu préciser la signification de "toute aplatie" ? Est-ce que les données sont au bon endroit ? Est-ce que tout est aplati ou que les données ?

La donnée dans la base est en projection 27582.


Je ne connais pas exactement tous les détails, mais je ne vois pas de code 27582 dans le code, est-ce que le système découvre tout seul la projection de tes données ?


Jérôme Cuinet
L'avantage de la Chine, c'est que le soleil se couche plus tard !

Hors ligne

 

#4 Wed 13 January 2010 16:14

Yves
Membre du bureau
Lieu: Aix-les-Bains
Date d'inscription: 22 Mar 2006
Messages: 9864
Site web

Re: Problème de projection avec OpenLayers - Google Maps - GeoJSON

Jérôme,

L'astuce est dans la requête :

$query_1 = 'SELECT ST_ASGEOJSON(ST_Transform(the_geom, 4326),5) FROM '.$bd_schema_1.'.'.$layer_config_1[$j]['bd_table'].' WHERE numreg = \'54\' ';


Les données sont reprojeté côté serveur.

Pourquoi les données sont applatie ? Parce que Google API utilise une projection mercator plate carré modifiée. En superposant des données en LatLong, cela affiche les données "aplaties".

Au sein d'OpenLayers, il y a une option qui permet de "dire" à OL que la projection est celle de Google, les données doivent être reprojeté. Il y a généralement deux stratégies :
1. envoyer des donnes en EPSG:900913 (donc modifier la requête)
2. reprojeter côté client via proj4js et d'autres config côté OL

Y.


Yves Jacolin, bénévole de l'association GeoRezo.net, agit au nom et pour le compte de l'association - Partageons ce qui nous départage !!  - GeoRezo vous aide ? Aidez GeoRezo !

Hors ligne

 

#5 Wed 13 January 2010 16:55

Jeirhome
Membre
Lieu: Liverion
Date d'inscription: 22 Aug 2006
Messages: 4298
Site web

Re: Problème de projection avec OpenLayers - Google Maps - GeoJSON

Pour résumer et voir si j'ai bien compris :

Le code ci-dessous fait la transformation des données dans le système de coordonnées de la carte, le système correspondant au code EPSG 4326.

Le code

Code:

    gphy = new OpenLayers.Layer.Google(
                "Google Physical",
                {type: G_PHYSICAL_MAP}
            );

        map.addLayer(gphy);

ajoute la couche Google mais n'effectue aucune transformation sur ce flux de données Google afin qu'il soit conforme à la carte. Donc ce ne sont pas les données qui sont aplaties, mais la couche Google qui n'est pas dans la bonne projection (La
EPSG::3857, WGS 84 / Pseudo-Mercator, qui en attendant une version officielle on a baptisé 900913, et qui n'a rien de plate carré big_smile).

Or on ne modifie pas le système de coordonnées du flux de Google (on ne peut pas ou c'est trop lourd en terme de temps de calcul), donc la solution est de tout changer, la projection de la carte et par la même occasion les données à afficher.


Jérôme Cuinet
L'avantage de la Chine, c'est que le soleil se couche plus tard !

Hors ligne

 

#6 Thu 14 January 2010 09:40

Tony VINCENT
Participant actif
Lieu: Poitiers
Date d'inscription: 13 Jan 2010
Messages: 86

Re: Problème de projection avec OpenLayers - Google Maps - GeoJSON

Bonjour,

merci pour toutes vos réponses.

Désolé, pour l'utilisation des balises. Il faut que je me familiarise avec le forum.


Suite aux différentes remarques que vous avez faites. J'ai refais des tests et maintenant cela fonctionne, la couche de donnée que j'affiche sur le fond de carte google, n'est plus aplatie.

Suite aux remarques de Yves, j'ai modifié la couche google en suivant la doc

sur doc.openlayers.org, section : "Spérical Mercator"


.

Code:

    map = new OpenLayers.Map("map", {
      projection: new OpenLayers.Projection("EPSG:900913")
    });

    gphy = new OpenLayers.Layer.Google("Google Physical",
              {'sphericalMercator': true,
               'maxExtent': new OpenLayers.Bounds(-218915.64898,5627599.76968,170607.44711,5981656.08465) // Extent Poitou-Charentes
              });

    
        map.addLayer(gphy);

Et ensuite, j'ai modifié le type de projection dans la requête. Remplacement de 4326 par 900913.

Maintenant, ma couche ce superpose bien.


Je remets le code en entier, pour ceux qui le veulent :

Code:

var map;

function init() {

    map = new OpenLayers.Map("map", {
      projection: new OpenLayers.Projection("EPSG:900913")
    });

    gphy = new OpenLayers.Layer.Google("Google Physical",
              {'sphericalMercator': true,
               'maxExtent': new OpenLayers.Bounds(-218915.64898,5627599.76968,170607.44711,5981656.08465) // Extent Poitou-Charentes
              });

    
        map.addLayer(gphy);


<?php

//// Boucle pour construitre l'ensemble des layers,
// en fonction de la variable "$layer_config"
for ($j=0;$j<sizeof($layer_config_1);$j++)
{

    //// Requête SQL
    $query_1 = 'SELECT ST_ASGEOJSON(ST_Transform(the_geom, 900913),5) FROM '.$bd_schema_1.'.'.$layer_config_1[$j]['bd_table'].' WHERE numreg = \'54\' ';

    //// Décommenter pour test
    //echo $query_1;

    //// Afficher un message d'erreur, s'il y a une erreur dans la connexion ou la requête SQL
    $result_1 = pg_query($dbconn, $query_1);
    if (!$result_1) {
        echo 'Une erreur s\'est produite '.$layer_config_1[$j]['lib_etendu'].'.';
        exit;
    }

////
$i = 1;

//// Construction du layer
echo 'var featurecollection = {
"type": "FeatureCollection",
              "features": [
                {"geometry": {
                    "type": "GeometryCollection",
                    "geometries": [
';

//// Boucle qui va recupérer les valeurs des enregistrements
while ($row_1 = pg_fetch_assoc($result_1))
{
    //// On affiche le résultat de l'enregistrement
    print_r( $row_1['st_asgeojson']);

    //// Ajouter une virgule après chaque enregistrement, sauf pour le dernier
    if ($i < pg_num_rows($result_1))
    {
        echo ',';
    }
   
    //// On incrémente $i
    $i++;
}

////
echo '                   ]
                },
                "type": "Feature",
                "properties": {"ID": "'.$j.'"}}
              ]
           };

';

////
echo 'var geojson_format = new OpenLayers.Format.GeoJSON();
    var '.$layer_config_1[$j]['lib'].' = new OpenLayers.Layer.Vector("'.$layer_config_1[$j]['lib_etendu'].'");
    map.addLayer('.$layer_config_1[$j]['lib'].');
    '.$layer_config_1[$j]['lib'].'.addFeatures(geojson_format.read(featurecollection));

';
}

?>

//////////////////////////////////////////////////////////////////////////////////////
//// Options de présentation de la carte
/////////////////////////////////////////////////////////////////////////////////////

    //// Permet de changer le fond de carte 
        map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':true}));
    //// Affichage de la barre de zoom
    map.addControl(new OpenLayers.Control.PanZoomBar());
    //// Lien permettant de réinitialiser la carte
    map.addControl(new OpenLayers.Control.Permalink());
    //// Affichage de la bar d'échelle
    map.addControl(new OpenLayers.Control.ScaleLine());
    //// Affichage d'imagette de positionnement
    map.addControl(new OpenLayers.Control.OverviewMap());
    //// 
    //map.addControl(new OpenLayers.Control.KeyboardDefaults());
    //// Positionnement de la souris
    map.addControl(new OpenLayers.Control.MousePosition());

    //// Recentrage de la carte sur le Poitou-Charentes
    map.zoomToMaxExtent();

//// Fin options de présentation
/////////////////////////////////////////////////////////////////////////////////////


        }

Hors ligne

 

Pied de page des forums

Powered by FluxBB