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 :
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 ...)
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
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
Jusque là ça marche.
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.

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
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...
Merci à vous!