#1 Thu 01 November 2007 18:36
- yoda
- Participant occasionnel
- Date d'inscription: 5 Sep 2007
- Messages: 15
découpages de raster en fonction de commune
Bonjour
j'ai un petit problème je dispose d'un raster sous arcview qui comporte en fonction des pixels les risques d'incendie, la commande est de découper ce raster en fonction des polygones des contours des communes et de récupérer sous format base de données les risques incendie . Je ne sais pas s'il existe un logiciel libre capable de fair çà. Je dispose de vertical mapper pour mapinfo et je ne sais pas comment transformer ce raster vers mapinfo(format asx)
merci de votre aide
Hors ligne
#2 Thu 01 November 2007 19:04
- Maurice
- Membre
- Lieu: Montpellier
- Date d'inscription: 5 Sep 2005
- Messages: 5331
Re: découpages de raster en fonction de commune
Bonjour
Un raster reste toujours un rectangle, borné aux limites d'une commune ou pas; simplement on peut mettre "à blanc" les pixels hors commune
Et un raster ne porte comme information que le code couleur de ses pixels
Pour le travail commandé, il faudrait envisager une vectorisation de l'image "classée"
ArcView +SpatialAnalyst font ça très bien, MapInfo+VerticalMapper aussi (je crois)
Hors ligne
#3 Thu 01 November 2007 21:06
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: découpages de raster en fonction de commune
Bonjour,
Il existe plusieurs possibilités, je ne sais pas si toutes existent de façon "libre" ou sous licence commerciale.
Récupérer la polyligne définissant le contour communal dans un format vectoriel courant.
Première solution définir un masque rectangulaire contenant la polyligne, l'appliquer au raster (c'est l'intérieur de la polyligne qui est transparent, et l'extérieur jusqu'aux limite du rectangle conteneur qui fait masque).
Deuxième solution mettre à blanc les pixels de l'image extérieurs à la polyligne, mais en dur dans le fichier image. Si vous programmez en VB je peux vous donner un bout de code qui fait ça.
Reste la problématique de la base de données, qui doit trouver une solution logiciel non ? Posez peut-être cette question spécifique sur le forum Esri de ce portail?
A+
Christophe
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#4 Sat 03 November 2007 10:38
- yoda
- Participant occasionnel
- Date d'inscription: 5 Sep 2007
- Messages: 15
Re: découpages de raster en fonction de commune
Bonjour
le programme vb m'intéresse reste à récupérer les vertex du polygones et à vectoriser l'image
Hors ligne
#5 Sat 03 November 2007 18:21
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: découpages de raster en fonction de commune
Bonjour,
Une précision, le raster dont vous parlez est formé d'une unique image ? Sous quel format, quelle profondeur de couleur ?
Une autre, comment est représenté le "risque incendie", une intensité (ou un dégradé) de couleur en fonction du risque ? (dans ce cas une vecto ne sert à rien), ou un ensemble de pixel représente une forme géomètrique ?
A+
Christophe
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#6 Sun 04 November 2007 08:31
- bernard lortic
- Participant assidu
- Lieu: crest 26
- Date d'inscription: 23 Jan 2006
- Messages: 549
- Site web
Re: découpages de raster en fonction de commune
Bonjour,
quelque fois je me dis que j'ai mal compris la question, tellement la reponse me
parait evidente. Pour cela aussi :
Pour moi, un raster est un des format de ma base de données.
Des operation de geo-jointure permet de passer d'un type a un autre; en l'occurance
de raster a zone, me semble-t-il.
La question est le pixel est-il plus grand que les zones ? Ou plus petit. Dans le premier cas on affectera a la zone la valeur du pixel ou du % de surface du pixel.
Dans le deuxieme cas on aura le choix entre plusieurs types d'aggregation.
Cela me semble la raison principale de la creation des lociels SIG. Ils ont surtout
eté ecrit pour cela.
En tous cas Savane le fait de facon nuturelle, innée dirais-je.
www.savgis.org
Cordialement
Bernard LORTIC IRD 93143 Bondy
http://www.bdvilles.ird.fr/lortic_pages … index.php3
http://www.bdvilles.ird.fr/lortic_pages … index.html
Hors ligne
#7 Mon 05 November 2007 11:03
- yoda
- Participant occasionnel
- Date d'inscription: 5 Sep 2007
- Messages: 15
Re: découpages de raster en fonction de commune
le format est le dégradé de couleur de format GRID de valeur 5 à 1 (je n'arrive pas à l'ouvrir avec mapinfo) est composé d'une unique image qui couvre un département français
merci
Hors ligne
#8 Mon 05 November 2007 18:28
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: découpages de raster en fonction de commune
Bonjour,
Je pense que vous devez rediriger vos questions vers le forum MapInfo
En effectuant au préalable une recherche sur ce forum.
Le format GRID n'est pas un format d'image au sens où, le code que je vous proposais l'entend.
Christophe
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#9 Mon 05 November 2007 22:36
- yoda
- Participant occasionnel
- Date d'inscription: 5 Sep 2007
- Messages: 15
Re: découpages de raster en fonction de commune
Bonjour
le format de l'image estadf après traitement dans spatial analyst votre code vb me seait utile
Hors ligne
#10 Tue 06 November 2007 08:48
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: découpages de raster en fonction de commune
Bonjour,
Vous trouverez ci-dessous un extrait de code VB6 qui implémente un algorithme d'extraction polygonale pour les rasters.
Le principe est le suivant:
Définition du rectangle mini englobant la polyligne.
Extraction de l'image contenue dans ce rectangle.
Création d'une image à blanc de la même taille (on peut mettre la couleur qu'on veut)
De bas en haut
Pour chaque ligne du raster
Calcul de l'intersection la ligne raster et de la polyligne.
Le résultat et sous forme de paires de valeur triées selon les x croissants. (s'il existe 4 points par exemple, on aura 2 paires (1,2) et (3,4) l'interval (2,3) étant hors de la polyligne)
Pour chaque paires de valeurs, conversion des résultat en adresse de début et de fin dans l'image en cours
Copie du segment mémoire de l'image source vers l'image destination.
Et on boucle
Si vous voulez implenter ce code dans un projet VB soyez attentif aux calculs d'adresse, car une erreur provoque une exception mémoire, qui vous vire illico même de l'IDE VB donc pas de debbugage possible.
Il vous faut de plus être famillier des structures DIB windows et des API.
Code:
Public Sub MakeExtraction(h As RealRegion) Dim r As GFL_RECT Dim dummy& 'calcul l'intersection de l'image avec le rectangle dummy& = GetzoneDIB(mdc, h) With mRectbitmap r.X = .Left r.Y = mDIBinfo.bmiHeader.biHeight - (.Top + .Bottom) r.w = .Right r.h = .Bottom End With 'utilisation de la dll LibGFL dispo à www.xnview.com gflLibraryInit dummy& = gflCrop(mGflBitmap, ByVal 0, r) If dummy& = 0 Then mDIBinfo = extGetDIBFromBitmap(mGflBitmap) mAncreX = h.Left mAncreY = h.Bottom SetEspaceBitmap End If gflLibraryExit End Sub Public Function ExtractFromPolyline(PL As PolyLigne) As Long Dim HmemTemp& Dim Tmpaddr& Dim dest& Dim org& Dim lign& Dim TabInter() As Interval Dim dy As Double Dim Yvalue As Double Dim dummy& Dim l& Dim f& Dim i& Dim j& Dim count& Dim h As RealRegion Dim TabPoint() As Geopoint 'defini le rectangle mini/polyline et fais l'extraction Set h = New RealRegion Set PL = PL.IntersecWithRec(mEspacebitmap, True) Set h = PL.Encadrante(True) h.Dessine mdc MakeExtraction h ' l'image est réduite au rectangle englobant la polyligne 'initialise tabpoint ReDim TabPoint(PL.Sommets.count - 1) For i& = 0 To PL.Sommets.count - 1 Set TabPoint(i&) = New Geopoint TabPoint(i&).X = PL.Sommets(Trim$(Str(i + 1&))).X TabPoint(i&).Y = PL.Sommets(Trim$(Str(i + 1&))).Y Next i& i& = 0 'reserve une zone tampon de la taille du bitmap et la rempli en blanc HmemTemp& = GlobalAlloc(GMEM_MOVEABLE, mDIBinfo.bmiHeader.biSizeImage) Tmpaddr& = GlobalLock(HmemTemp&) Call FillMemory(Tmpaddr&, mDIBinfo.bmiHeader.biSizeImage, 255) dummy& = GlobalUnlock(HmemTemp&) 'défini le pas réel If mEstGeoref Then dy = mTfwY Else dy = 1 / mDIBinfo.bmiHeader.biYPelsPerMeter * mEchelle End If Yvalue = mEspacebitmap.Bottom For i& = 0 To mDIBinfo.bmiHeader.biHeight TabInter = IntersectionYPolyline(TabPoint, Yvalue) 'si il existe un interval On Error Resume Next Err.Clear count& = UBound(TabInter) If Err.Number = 9 Then 'ne touche à rien Else 'calcul l'adresse de la ligne en cours lign& = i& * byteperscanline(mDIBinfo.bmiHeader.biWidth, mDIBinfo.bmiHeader.biBitCount) For j& = 0 To count& If TabInter(j&).start < h.Left Then TabInter(j&).start = h.Left End If If TabInter(j&).end > h.Right Then TabInter(j&).end = h.Right End If mdc.pointreal TabInter(j&).start, Yvalue, RGB(255, 0, 0) mdc.pointreal TabInter(j&).end, Yvalue, RGB(0, 255, 0) 'calcul l'adresse de départ l& = CLng((TabInter(j&).start - mEspacebitmap.Left) * mDIBinfo.bmiHeader.biXPelsPerMeter / mEchelle) Select Case mDIBinfo.bmiHeader.biBitCount Case 1 l& = l& \ 8 Case 8 Case 24 l& = l& * 3 Case 32 l& = l& * 4 End Select l& = lign& + l& ' calcul l'adresse de fin f& = CLng((TabInter(j&).end - TabInter(j&).start) * mDIBinfo.bmiHeader.biXPelsPerMeter / mEchelle) Select Case mDIBinfo.bmiHeader.biBitCount Case 1 f& = f& \ 8 + 1 Case 8 f& = f& + 1 Case 24 f& = f& * 3 + 3 Case 32 f& = f& * 4 + 4 End Select 'copie l'interval dans le bitmap temporaire org& = GlobalLock(mGflBitmap.Data) dest& = GlobalLock(HmemTemp&) org& = org& + l& dest& = dest& + l& Call CopyMemory(dest&, org&, f&) dummy& = GlobalUnlock(mGflBitmap.Data) dummy& = GlobalUnlock(HmemTemp&) Next j& End If Erase TabInter Yvalue = Yvalue + dy Next i& dest& = GlobalLock(mGflBitmap.Data) org& = GlobalLock(HmemTemp&) Call CopyMemory(dest&, org&, mDIBinfo.bmiHeader.biSizeImage) dummy& = GlobalUnlock(mGflBitmap.Data) dummy& = GlobalUnlock(HmemTemp&) GlobalFree (HmemTemp&) For i& = 0 To PL.Sommets.count Set TabPoint(i&) = Nothing Next i& Erase TabPoint End Function Private Function IntersectionYPolyline(TabGeoPoint() As Geopoint, Yvalue As Double) As Interval() Dim count& Dim i& Dim j& Dim Index& Dim a As Double Dim b As Double Dim tabres() As Interval Dim p1 As POINTGEO Dim p2 As POINTGEO Dim ptmp() As POINTGEO On Error Resume Next count& = UBound(TabGeoPoint) If count& = 0 Or count& = -1 Then Call MsgBox("La polyligne contient 0 ou 1 element !!", vbExclamation, "Calcul Vectoriel") On Error GoTo 0 Exit Function Else On Error GoTo 0 For i& = 0 To count& If i& = count& Then If TabGeoPoint(i&).Y < TabGeoPoint(0).Y Then p1.X = TabGeoPoint(i&).X p1.Y = TabGeoPoint(i&).Y p2.X = TabGeoPoint(0).X p2.Y = TabGeoPoint(0).Y Else p2.X = TabGeoPoint(i&).X p2.Y = TabGeoPoint(i&).Y p1.X = TabGeoPoint(0).X p1.Y = TabGeoPoint(0).Y End If Else If TabGeoPoint(i&).Y < TabGeoPoint(i& + 1).Y Then p1.X = TabGeoPoint(i&).X p1.Y = TabGeoPoint(i&).Y p2.X = TabGeoPoint(i& + 1).X p2.Y = TabGeoPoint(i& + 1).Y Else p2.X = TabGeoPoint(i&).X p2.Y = TabGeoPoint(i&).Y p1.X = TabGeoPoint(i& + 1).X p1.Y = TabGeoPoint(i& + 1).Y End If End If If p1.Y <= Yvalue And Yvalue <= p2.Y Then a = p2.X - p1.X On Error Resume Next Err.Clear Index& = UBound(ptmp) If Err.Number = 9 Then Index& = -1 ReDim Preserve ptmp(Index& + 1) On Error GoTo 0 If a = 0 Then ptmp(Index& + 1).X = p1.X ptmp(Index& + 1).Y = Yvalue Else a = (p2.Y - p1.Y) / a b = p1.Y - a * p1.X If a <> 0 Then ptmp(Index& + 1).X = (Yvalue - b) / a ptmp(Index& + 1).Y = Yvalue Else ptmp(Index& + 1).X = p2.X ptmp(Index& + 1).Y = Yvalue End If End If If p1.Y = Yvalue Or p2.Y = Yvalue Then ptmp(Index& + 1).Y = -1 End If Next i& 'trie le tableau par x croissant On Error Resume Next Err.Clear Index& = UBound(ptmp) If Err.Number = 9 Then On Error GoTo 0 Exit Function End If For i& = 0 To Index& 'p1.X = ptmp(i&).X 'p1.Y = ptmp(i&).Y For j& = i& + 1 To Index& 'si plus petit swap If ptmp(j&).X < ptmp(i&).X Then p2.X = ptmp(i&).X p2.Y = ptmp(i&).Y ptmp(i&).X = ptmp(j&).X ptmp(i&).Y = ptmp(j&).Y ptmp(j&).X = p2.X ptmp(j&).Y = p2.Y End If Next j& Next i& count& = 0 Index& = 0 Do While Index& < UBound(ptmp) + 1 ReDim Preserve tabres(count&) If ptmp(Index&).Y <> Yvalue Then tabres(count&).start = ptmp(Index&).X tabres(count&).end = ptmp(Index&).X count& = count& + 1 Index = Index& + 1 Else If tabres(count&).start = 0 Then tabres(count&).start = ptmp(Index&).X Index& = Index& + 1 Else tabres(count&).end = ptmp(Index&).X Index& = Index& + 1 count& = count& + 1 End If End If Loop IntersectionYPolyline = tabres End If End Function
A+
Christophe
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#11 Tue 06 November 2007 10:10
- yoda
- Participant occasionnel
- Date d'inscription: 5 Sep 2007
- Messages: 15
Re: découpages de raster en fonction de commune
Merci de votre aide, il me reste à écrire la procédure main pour charger le shp des communes si vous pouviez m'indiquer où est ce que je peux trouver de la documentation sur ce chargement dans vb
encore une fois merci celà me sera très utile
Hors ligne