Bonjour tout le monde.
Je manipule des données de type 'geography' et je rencontre un problème dans l'éxécution de mon code. J'ai une erreur spécifiant :
"System.FormatException : 24115 : l'entrée WKB (well-know binary) n'est pas valide".
J'ai compris que je rentre un type de données non valide, mais j'arrive pas à identifier ce qui cloche.
Pour vous situer mon travail.
J'ai une base de fichier texte contenant des couvertures satellites définient par tous les points formant leur contours (des sortes de cercles, patatoïdes). J'ai coupé le fichier pour voir à quoi y ressemble :
J'importe tous ces points dans ma base de données. Et les convertit en POINT de type 'geography' via :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 beam_id;sat_name;gain;lon;sat 1;906z41downlink;-3.00;125.091;-20.655 1;906z41downlink;-3.00;125.299;-20.632 1;906z41downlink;-3.00;126.144;-20.593 1;906z41downlink;-3.00;127.337;-20.494 1;906z41downlink;-3.00;130.851;-20.147 1;906z41downlink;-3.00;131.301;-20.022 1;906z41downlink;-3.00;132.011;-19.896 1;906z41downlink;-3.00;133.043;-19.654 1;906z41downlink;-3.00;134.155;-19.499 1;906z41downlink;-3.00;134.841;-19.253 (... d autres points avec le même beam_id ...) 2;906z41downlink;-1.00;141.187;24.476 2;906z41downlink;-1.00;141.298;24.487 2;906z41downlink;-1.00;141.443;24.501 2;906z41downlink;-1.00;142.351;24.596 2;906z41downlink;-1.00;144.550;25.075 2;906z41downlink;-1.00;144.529;25.332 (... d autres points avec le même beam_id ...) 3;906z41downlink;-4.00;105.037;-20.751 3;906z41downlink;-4.00;104.821;-20.626 3;906z41downlink;-4.00;104.589;-20.499 3;906z41downlink;-4.00;103.952;-20.091 3;906z41downlink;-4.00;103.279;-19.693 3;906z41downlink;-4.00;103.102;-19.571 3;906z41downlink;-4.00;102.946;-19.467 (... d autres points avec le même beam_id ...) (... etc ...)
Jusque là ça marche.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 CREATE TABLE sat_beam ( beam_id int NOT NULL, sat_ref char(50) NOT NULL, gain real, longitude real, latitude real ); -- Add coordinates to sat_beam ALTER TABLE [sat_beam] ADD coordinate geography; UPDATE [dbo].[sat_beam] SET [coordinate] = geography::STPointFromText('POINT(' + CAST([longitude] AS VARCHAR(20)) + ' ' + CAST([latitude] AS VARCHAR(20)) + ')', 4326); GO
J'ai donc un table remplie de plein de points. Les différentes couvertures sont identifiées par le beam_id.
Je souhaite donc parcourir cette table et créer autant de POLYGON qu'il y a de couverture différentes. Ici ça se visualise par, dès que le beam_id change on a un nouveau polygon.
Voici le code que j'ai mis en place (très très fortement inspiré d'ici)
Mon bon ça marche pas. Il semblerait que je génère pas bien les @CoordinateStream de type "varbinary(max)", ce qu'y ferait que le WKB n'est pas valide.
Quelqu'un aurait une idée de mon problème?? J'intuite un MakeValid() quelque part mais je ne sais pas trop où, quand, comment l'utiliser...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 --- Init variables DECLARE @Point geography DECLARE @CoordinateStream varbinary(max) DECLARE @i int DECLARE @valb int -- DECLARE @Bid int DECLARE @RefS char(50) DECLARE @Gain real DECLARE @PrevRefS char(50) DECLARE @PrevGain real DECLARE @Cpt int -- SET @i = 0 SET @valb = 2 -- comparing to b_id SET @Cpt = 0 -- Cursor : check every row from sat_beam TABLE -- Insert each polygon in the stream DECLARE GeomCursor CURSOR FOR SELECT beam_id,sat_ref,gain,coordinate FROM sat_beam WITH (NOLOCK); OPEN GeomCursor; FETCH NEXT FROM GeomCursor INTO @Bid,@RefS,@Gain,@Point; WHILE @@FETCH_STATUS = 0 BEGIN -- First time the cursor look for the table IF (@i=0) BEGIN SET @CoordinateStream = SUBSTRING(@Point.STAsBinary(),6,16) END -- Change of beam ID value IF @valb = @Bid BEGIN INSERT INTO ListOfBeam ( nb_points ,sat_ref, gain, stream ) VALUES ( @i-@Cpt,@PrevRefS,@PrevGain,@CoordinateStream ) -- Init and update for new beam SET @CoordinateStream = NULL SET @CoordinateStream = SUBSTRING(@Point.STAsBinary(),6,16) SET @valb = @valb + 1 SET @Cpt = @i END ELSE BEGIN SET @CoordinateStream = @CoordinateStream + SUBSTRING(@Point.STAsBinary(),6,16) END; SET @i = @i+1 SET @PrevRefS = @RefS SET @PrevGain = @Gain FETCH NEXT FROM GeomCursor INTO @Bid,@RefS,@Gain,@Point; END; CLOSE GeomCursor; DEALLOCATE GeomCursor; GO -- To build a polygon from this 'coordinatestream' ALTER TABLE ListOfBeam ADD perimeter geography; GO -- Visualize polygon created SELECT geography::STPolyFromWKB( 0x01 -- Again, sepcify big-endian byte order + 0x03000000 -- This is a 4-byte value showing that we are building a polygon + 0x01000000 -- The number of rings in the polygon. Let's keep it simple and assume we only have an exterior ring + CONVERT(varbinary,REVERSE(CONVERT(varbinary,[nb_points]+1))) -- There is one more point in the polygon definition than in the original set of points, since we repeat the start/end point + stream + SUBSTRING(stream,1,16) -- We take the co-ordinate stream, and repeat the first point co-ordinates to close the ring ,4326).STAsText() FROM ListOfBeam; GO
Merci à vous!![]()
Partager