GeoJsonBoundingBoxSerializer.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Linq;
  17. using MongoDB.Bson;
  18. using MongoDB.Bson.IO;
  19. using MongoDB.Bson.Serialization;
  20. using MongoDB.Bson.Serialization.Serializers;
  21. namespace MongoDB.Driver.GeoJsonObjectModel.Serializers
  22. {
  23. /// <summary>
  24. /// Represents a serializer for a GeoJsonBoundingBox value.
  25. /// </summary>
  26. /// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
  27. public class GeoJsonBoundingBoxSerializer<TCoordinates> : ClassSerializerBase<GeoJsonBoundingBox<TCoordinates>> where TCoordinates : GeoJsonCoordinates
  28. {
  29. // private fields
  30. private readonly IBsonSerializer<TCoordinates> _coordinatesSerializer = BsonSerializer.LookupSerializer<TCoordinates>();
  31. // protected methods
  32. /// <summary>
  33. /// Deserializes a value.
  34. /// </summary>
  35. /// <param name="context">The deserialization context.</param>
  36. /// <param name="args">The deserialization args.</param>
  37. /// <returns>The value.</returns>
  38. protected override GeoJsonBoundingBox<TCoordinates> DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
  39. {
  40. var bsonReader = context.Reader;
  41. var flattenedArray = BsonArraySerializer.Instance.Deserialize(context);
  42. if ((flattenedArray.Count % 2) != 0)
  43. {
  44. throw new FormatException("Bounding box array does not have an even number of values.");
  45. }
  46. var half = flattenedArray.Count / 2;
  47. // create a dummy document with a min and a max and then deserialize the min and max coordinates from there
  48. var document = new BsonDocument
  49. {
  50. { "min", new BsonArray(flattenedArray.Take(half)) },
  51. { "max", new BsonArray(flattenedArray.Skip(half)) }
  52. };
  53. using (var documentReader = new BsonDocumentReader(document))
  54. {
  55. var documentContext = BsonDeserializationContext.CreateRoot(documentReader);
  56. documentReader.ReadStartDocument();
  57. documentReader.ReadName("min");
  58. var min = _coordinatesSerializer.Deserialize(documentContext);
  59. documentReader.ReadName("max");
  60. var max = _coordinatesSerializer.Deserialize(documentContext);
  61. documentReader.ReadEndDocument();
  62. return new GeoJsonBoundingBox<TCoordinates>(min, max);
  63. }
  64. }
  65. /// <summary>
  66. /// Serializes a value.
  67. /// </summary>
  68. /// <param name="context">The serialization context.</param>
  69. /// <param name="args">The serialization args.</param>
  70. /// <param name="value">The value.</param>
  71. protected override void SerializeValue(BsonSerializationContext context, BsonSerializationArgs args, GeoJsonBoundingBox<TCoordinates> value)
  72. {
  73. var bsonWriter = context.Writer;
  74. // serialize min and max to a dummy document and then flatten the two arrays and serialize that
  75. var document = new BsonDocument();
  76. using (var documentWriter = new BsonDocumentWriter(document))
  77. {
  78. var documentContext = BsonSerializationContext.CreateRoot(documentWriter);
  79. documentWriter.WriteStartDocument();
  80. documentWriter.WriteName("min");
  81. _coordinatesSerializer.Serialize(documentContext, value.Min);
  82. documentWriter.WriteName("max");
  83. _coordinatesSerializer.Serialize(documentContext, value.Max);
  84. documentWriter.WriteEndDocument();
  85. }
  86. var flattenedArray = new BsonArray();
  87. flattenedArray.AddRange(document["min"].AsBsonArray);
  88. flattenedArray.AddRange(document["max"].AsBsonArray);
  89. BsonArraySerializer.Instance.Serialize(context, flattenedArray);
  90. }
  91. }
  92. }